jekyll-spaceship 0.8.5 → 0.9.2
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/.rspec +3 -0
- data/.travis.yml +6 -6
- data/README.md +117 -23
- data/jekyll-spaceship.gemspec +1 -1
- data/lib/jekyll-spaceship/cores/config.rb +1 -1
- data/lib/jekyll-spaceship/cores/manager.rb +1 -1
- data/lib/jekyll-spaceship/cores/processor.rb +34 -1
- data/lib/jekyll-spaceship/processors/mathjax-processor.rb +15 -4
- data/lib/jekyll-spaceship/processors/media-processor.rb +234 -0
- data/lib/jekyll-spaceship/processors/mermaid-processor.rb +6 -20
- data/lib/jekyll-spaceship/processors/plantuml-processor.rb +8 -22
- data/lib/jekyll-spaceship/processors/table-processor.rb +70 -3
- data/lib/jekyll-spaceship/version.rb +1 -1
- metadata +7 -6
- data/lib/jekyll-spaceship/processors/video-processor.rb +0 -139
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 604e55f37a3597c851c56fd267f316eea0a180adcb8613c0908efa9f5ea87869
|
4
|
+
data.tar.gz: a32c960d432a348eb583d2e5d114f66564de56e2726b680765166bce86adbd6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f8383046d4a550ddacd859e14699b90b7a92d3759ebddf34430a8cbe421bfe1334f9a80186b80942aaff96a5802415ff7d01b78ec70939719aa483686238778
|
7
|
+
data.tar.gz: c9c98d831503df109e943d49030c7a6b7d0a37cd0d1eb0dba6fe39f555ee05ceaf5550d8cbcab10ec8160eb7bdc559db9ca8bcd6a7ec3ddefc813b97ecb7a585
|
data/.rspec
ADDED
data/.travis.yml
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
language: ruby
|
2
2
|
cache: bundler
|
3
3
|
rvm:
|
4
|
-
- 2.7
|
5
|
-
- 2.3
|
4
|
+
- 2.7
|
5
|
+
- 2.3
|
6
6
|
env:
|
7
7
|
global:
|
8
|
-
|
8
|
+
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
9
9
|
matrix:
|
10
|
-
|
10
|
+
- JEKYLL_VERSION="~> 3.8"
|
11
11
|
matrix:
|
12
12
|
include:
|
13
13
|
- rvm: 2.7
|
@@ -15,8 +15,8 @@ matrix:
|
|
15
15
|
- rvm: 2.7
|
16
16
|
env: JEKYLL_VERSION=">= 4.0.0"
|
17
17
|
before_install:
|
18
|
-
- gem update --system
|
19
|
-
- gem install bundler
|
18
|
+
- gem update --system
|
19
|
+
- gem install bundler
|
20
20
|
before_script: bundle update
|
21
21
|
script: script/cibuild
|
22
22
|
notifications:
|
data/README.md
CHANGED
@@ -101,16 +101,20 @@ Spaceship is a minimalistic, powerful and extremely customizable [Jekyll](https:
|
|
101
101
|
- [1.3 Headerless](#headerless)
|
102
102
|
- [1.4 Cell Alignment](#cell-alignment)
|
103
103
|
- [1.5 Cell Markdown](#cell-markdown)
|
104
|
+
- [1.6 Cell Inline Attributes](#cell-inline-attributes)
|
104
105
|
- [2. MathJax Usage](#2-mathjax-usage)
|
105
106
|
- [2.1 Performance Optimization](#21-performance-optimization)
|
106
107
|
- [2.2 How to use?](#22-how-to-use)
|
107
108
|
- [3. PlantUML Usage](#3-plantuml-usage)
|
108
109
|
- [4. Mermaid Usage](#4-mermaid-usage)
|
109
|
-
- [5.
|
110
|
+
- [5. Media Usage](#5-media-usage)
|
110
111
|
- [5.1 Youtube Usage](#youtube-usage)
|
111
112
|
- [5.2 Vimeo Usage](#vimeo-usage)
|
112
113
|
- [5.3 DailyMotion Usage](#dailymotion-usage)
|
113
|
-
- [5.4
|
114
|
+
- [5.4 Spotify Usage](#spotify-usage)
|
115
|
+
- [5.5 SoundCloud Usage](#soundcloud-usage)
|
116
|
+
- [5.6 General Video Usage](#general-video-usage)
|
117
|
+
- [5.7 General Audio Usage](#general-audio-usage)
|
114
118
|
- [6. Hybrid HTML with Markdown](#6-hybrid-html-with-markdown)
|
115
119
|
- [7. Markdown Polyfill](#7-markdown-polyfill)
|
116
120
|
- [7.1 Escape Ordered List](#71-escape-ordered-list)
|
@@ -142,7 +146,7 @@ plugins:
|
|
142
146
|
|
143
147
|
**💡 Tip:** Note that GitHub Pages runs in `safe` mode and only allows [a set of whitelisted plugins](https://pages.github.com/versions/). To use the gem in GitHub Pages, you need to build locally or use CI (e.g. [travis](https://travis-ci.org/), [github workflow](https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow)) and deploy to your `gh-pages` branch.
|
144
148
|
|
145
|
-
### Additions
|
149
|
+
### Additions for Unlimited GitHub Pages
|
146
150
|
|
147
151
|
* Here is a GitHub Action named [jekyll-deploy-action](https://github.com/jeffreytse/jekyll-deploy-action) for Jekyll site deployment conveniently. 👍
|
148
152
|
* Here is a [Jekyll site](https://github.com/jeffreytse/jekyll-jeffreytse-blog) using Travis to build and deploy to GitHub Pages for your references.
|
@@ -161,16 +165,20 @@ jekyll-spaceship:
|
|
161
165
|
- plantuml-processor
|
162
166
|
- mermaid-processor
|
163
167
|
- polyfill-processor
|
164
|
-
-
|
168
|
+
- media-processor
|
165
169
|
- emoji-processor
|
166
170
|
- element-processor
|
167
171
|
mathjax-processor:
|
168
|
-
src:
|
172
|
+
src:
|
173
|
+
- https://polyfill.io/v3/polyfill.min.js?features=es6
|
174
|
+
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
|
169
175
|
config:
|
170
|
-
|
176
|
+
tex:
|
171
177
|
inlineMath:
|
172
178
|
- ['$','$']
|
173
179
|
- ['\(','\)']
|
180
|
+
svg:
|
181
|
+
fontCache: 'global'
|
174
182
|
plantuml-processor:
|
175
183
|
mode: default # mode value 'pre-fetch' for fetching image at building stage
|
176
184
|
css:
|
@@ -178,7 +186,7 @@ jekyll-spaceship:
|
|
178
186
|
syntax:
|
179
187
|
code: 'plantuml!'
|
180
188
|
custom: ['@startuml', '@enduml']
|
181
|
-
src: http://www.plantuml.com/plantuml/
|
189
|
+
src: http://www.plantuml.com/plantuml/svg/
|
182
190
|
mermaid-processor:
|
183
191
|
mode: default # mode value 'pre-fetch' for fetching image at building stage
|
184
192
|
css:
|
@@ -189,14 +197,14 @@ jekyll-spaceship:
|
|
189
197
|
config:
|
190
198
|
theme: default
|
191
199
|
src: https://mermaid.ink/svg/
|
192
|
-
|
200
|
+
media-processor:
|
193
201
|
default:
|
194
|
-
id: '
|
195
|
-
class: '
|
202
|
+
id: 'media-{id}'
|
203
|
+
class: 'media'
|
196
204
|
width: '100%'
|
197
205
|
height: 350
|
198
|
-
|
199
|
-
style: 'max-width: 600px'
|
206
|
+
frameborder: 0
|
207
|
+
style: 'max-width: 600px; outline: none;'
|
200
208
|
allow: 'encrypted-media; picture-in-picture'
|
201
209
|
emoji-processor:
|
202
210
|
css:
|
@@ -534,6 +542,61 @@ Rowspan is 4
|
|
534
542
|
</tbody>
|
535
543
|
</table>
|
536
544
|
|
545
|
+
#### Cell Inline Attributes
|
546
|
+
|
547
|
+
This feature is very useful for custom cell such as using inline style. (e.g., background, color, font)
|
548
|
+
The idea and syntax comes from the [Maruku](http://maruku.rubyforge.org/) package.
|
549
|
+
|
550
|
+
[](https://kramdown.gettalong.org/syntax.html#block-ials)
|
551
|
+
|
552
|
+
Following are some examples of attributes definitions (ALDs) and afterwards comes the syntax explanation:
|
553
|
+
|
554
|
+
```markdown
|
555
|
+
{:ref-name: #id .cls1 .cls2}
|
556
|
+
{:second: ref-name #id-of-other title="hallo you"}
|
557
|
+
{:other: ref-name second}
|
558
|
+
```
|
559
|
+
|
560
|
+
An ALD line has the following structure:
|
561
|
+
|
562
|
+
- a left brace, optionally preceded by up to three spaces,
|
563
|
+
- followed by a colon, the id and another colon,
|
564
|
+
- followed by attribute definitions (allowed characters are backslash-escaped closing braces or any character except a not escaped closing brace),
|
565
|
+
- followed by a closing brace and optional spaces until the end of the line.
|
566
|
+
|
567
|
+
If there is more than one ALD with the same reference name, the attribute definitions of all the ALDs are processed like they are defined in one ALD.
|
568
|
+
|
569
|
+
An inline attribute list (IAL) is used to attach attributes to another element.
|
570
|
+
Here are some examples for span IALs:
|
571
|
+
|
572
|
+
```markdown
|
573
|
+
{: #id .cls1 .cls2} <!-- #id <=> id="id", .cls1 .cls2 <=> class="cls1 cls2" -->
|
574
|
+
{: ref-name title="hallo you"}
|
575
|
+
{: ref-name class='.cls3' .cls4}
|
576
|
+
```
|
577
|
+
|
578
|
+
Here is an example for custom table cell with IAL:
|
579
|
+
|
580
|
+
```markdown
|
581
|
+
{:color-style: style="background: black;"}
|
582
|
+
{:color-style: style="color: white;"}
|
583
|
+
{:text-style: style="font-weight: 800; text-decoration: underline;"}
|
584
|
+
|
585
|
+
|: Here's an Inline Attribute Lists example :||||
|
586
|
+
| ------- | ------------------ | -------------------- | ------------------ |
|
587
|
+
|: :|: <div style="color: red;"> < Normal HTML Block > </div> :|||
|
588
|
+
| ^^ | Red {: .cls style="background: orange" } |||
|
589
|
+
| ^^ IALs | Green {: #id style="background: green; color: white" } |||
|
590
|
+
| ^^ | Blue {: style="background: blue; color: white" } |||
|
591
|
+
| ^^ | Black {: color-style text-style } |||
|
592
|
+
```
|
593
|
+
|
594
|
+
Code above would be parsed as:
|
595
|
+
|
596
|
+
<img width="580px" src="https://user-images.githubusercontent.com/9413601/88461592-738afb00-ced7-11ea-9aac-3179023742b0.png" alt="IALs">
|
597
|
+
|
598
|
+
Additionally, [here](https://kramdown.gettalong.org/syntax.html#block-ials) you can learn more details about IALs.
|
599
|
+
|
537
600
|
### 2. MathJax Usage
|
538
601
|
|
539
602
|
[MathJax](http://www.mathjax.org/) is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all modern browsers.
|
@@ -574,7 +637,7 @@ Code above would be parsed as:
|
|
574
637
|
|
575
638
|
### 3. PlantUML Usage
|
576
639
|
|
577
|
-
[PlantUML](
|
640
|
+
[PlantUML](https://plantuml.com) is a component that allows to quickly write:
|
578
641
|
|
579
642
|
- sequence diagram,
|
580
643
|
- use case diagram,
|
@@ -645,25 +708,31 @@ Code above would be parsed as:
|
|
645
708
|
|
646
709
|

|
647
710
|
|
648
|
-
### 5.
|
711
|
+
### 5. Media Usage
|
649
712
|
|
650
|
-
How often did you find yourself googling "**How to embed a video in markdown?**"
|
713
|
+
How often did you find yourself googling "**How to embed a video/audio in markdown?**"
|
651
714
|
|
652
|
-
While its not possible to embed a video in markdown, the best and easiest
|
715
|
+
While its not possible to embed a video/audio in markdown, the best and easiest
|
716
|
+
way is to extract a frame from the video/audio. To add videos/audios to your
|
717
|
+
markdown files easier I developped this tool for you, and it will parse the
|
718
|
+
video/audio link inside the image block automatically.
|
653
719
|
|
654
|
-
**For now, these
|
720
|
+
**For now, these media links parsing are provided:**
|
655
721
|
|
656
722
|
- Youtube
|
657
723
|
- Vimeo
|
658
724
|
- DailyMotion
|
659
|
-
-
|
725
|
+
- Spotify
|
726
|
+
- SoundCloud
|
727
|
+
- General Video ( mp4 | avi | ogg | ogv | webm | 3gp | flv | mov ... )
|
728
|
+
- General Audio ( mp3 | wav | ogg | mid | midi | aac | wma ... )
|
660
729
|
|
661
|
-
There are two ways to embed a video in your Jekyll blog page:
|
730
|
+
There are two ways to embed a video/audio in your Jekyll blog page:
|
662
731
|
|
663
732
|
Inline-style:
|
664
733
|
|
665
734
|
```markdown
|
666
|
-

|
667
736
|
```
|
668
737
|
|
669
738
|
Reference-style:
|
@@ -671,10 +740,10 @@ Reference-style:
|
|
671
740
|
```markdown
|
672
741
|
![][{reference}]
|
673
742
|
|
674
|
-
[{reference}]: {
|
743
|
+
[{reference}]: {media-link}
|
675
744
|
```
|
676
745
|
|
677
|
-
For configuring
|
746
|
+
For configuring media attributes (e.g, width, height), just adding query string to
|
678
747
|
the link as below:
|
679
748
|
|
680
749
|
```markdown
|
@@ -707,6 +776,22 @@ the link as below:
|
|
707
776
|

|
708
777
|
```
|
709
778
|
|
779
|
+
#### Spotify Usage
|
780
|
+
|
781
|
+
```markdown
|
782
|
+

|
783
|
+
```
|
784
|
+
|
785
|
+
<image width="600" src="https://user-images.githubusercontent.com/9413601/89762618-5d11b000-db23-11ea-81db-35cc3682b234.png">
|
786
|
+
|
787
|
+
#### SoundCloud Usage
|
788
|
+
|
789
|
+
```markdown
|
790
|
+

|
791
|
+
```
|
792
|
+
|
793
|
+
<image width="600" src="https://user-images.githubusercontent.com/9413601/89762969-1c666680-db24-11ea-97e3-4340f7fac7ac.png">
|
794
|
+
|
710
795
|
#### General Video Usage
|
711
796
|
|
712
797
|
```markdown
|
@@ -717,6 +802,15 @@ the link as below:
|
|
717
802
|

|
718
803
|
```
|
719
804
|
|
805
|
+
#### General Audio Usage
|
806
|
+
|
807
|
+
```markdown
|
808
|
+

|
809
|
+
|
810
|
+

|
811
|
+
```
|
812
|
+
|
813
|
+
<image width="300" src="https://user-images.githubusercontent.com/9413601/89762143-68181080-db22-11ea-8467-e8b2a8a96ae5.png">
|
720
814
|
|
721
815
|
### 6. Hybrid HTML with Markdown
|
722
816
|
|
@@ -890,7 +984,7 @@ jekyll-spaceship:
|
|
890
984
|
css:
|
891
985
|
- a: # Replce all `a` tags
|
892
986
|
props: #
|
893
|
-
loading: lazy # Replace `
|
987
|
+
loading: lazy # Replace `loading` value to `lazy`
|
894
988
|
```
|
895
989
|
|
896
990
|
In case you want to prevent loading some images/iframes lazily, add
|
data/jekyll-spaceship.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = Jekyll::Spaceship::VERSION
|
10
10
|
spec.authors = ["jeffreytse"]
|
11
11
|
spec.email = ["jeffreytse.mail@gmail.com"]
|
12
|
-
spec.summary = "A Jekyll plugin to provide powerful supports for table, mathjax, plantuml, mermaid, emoji, video, youtube, vimeo, dailymotion, etc."
|
12
|
+
spec.summary = "A Jekyll plugin to provide powerful supports for table, mathjax, plantuml, mermaid, emoji, video, audio, youtube, vimeo, dailymotion, spotify, soundcloud, etc."
|
13
13
|
spec.homepage = "https://github.com/jeffreytse/jekyll-spaceship"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -160,7 +160,7 @@ module Jekyll::Spaceship
|
|
160
160
|
elsif type == :math
|
161
161
|
regex = /(((?<!\\)\${1,2})[^\n]*?\1)/
|
162
162
|
elsif type == :liquid_filter
|
163
|
-
regex = /((?<!\\)\{\{[^\n]*?\}\})/
|
163
|
+
regex = /((?<!\\)((\{\{[^\n]*?\}\})|(\{%[^\n]*?%\})))/
|
164
164
|
end
|
165
165
|
next if regex.nil?
|
166
166
|
content.scan(regex) do |match_data|
|
@@ -192,5 +192,38 @@ module Jekyll::Spaceship
|
|
192
192
|
end
|
193
193
|
content
|
194
194
|
end
|
195
|
+
|
196
|
+
def self.fetch_img_data(url)
|
197
|
+
begin
|
198
|
+
res = Net::HTTP.get_response URI(url)
|
199
|
+
raise res.body unless res.is_a?(Net::HTTPSuccess)
|
200
|
+
content_type = res.header['Content-Type']
|
201
|
+
raise 'Unknown content type!' if content_type.nil?
|
202
|
+
content_body = res.body.force_encoding('UTF-8')
|
203
|
+
return {
|
204
|
+
'type' => content_type,
|
205
|
+
'body' => content_body
|
206
|
+
}
|
207
|
+
rescue StandardError => msg
|
208
|
+
logger.log msg
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.make_img_tag(data)
|
213
|
+
css_class = data['class']
|
214
|
+
type = data['type']
|
215
|
+
body = data['body']
|
216
|
+
if type == 'url'
|
217
|
+
"<img class=\"#{css_class}\" src=\"#{body}\">"
|
218
|
+
elsif type.include?('svg')
|
219
|
+
body.gsub(/\<\?xml.*?\?>/, '')
|
220
|
+
.gsub(/<!--[^\0]*?-->/, '')
|
221
|
+
.sub(/<svg /, "<svg class=\"#{css_class}\" ")
|
222
|
+
else
|
223
|
+
body = Base64.encode64(body)
|
224
|
+
body = "data:#{type};base64, #{body}"
|
225
|
+
"<img class=\"#{css_class}\" src=\"#{body}\">"
|
226
|
+
end
|
227
|
+
end
|
195
228
|
end
|
196
229
|
end
|
@@ -6,9 +6,13 @@ module Jekyll::Spaceship
|
|
6
6
|
class MathjaxProcessor < Processor
|
7
7
|
def self.config
|
8
8
|
{
|
9
|
-
'src' =>
|
9
|
+
'src' => [
|
10
|
+
'https://polyfill.io/v3/polyfill.min.js?features=es6',
|
11
|
+
'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js',
|
12
|
+
],
|
10
13
|
'config' => {
|
11
|
-
'
|
14
|
+
'tex' => { 'inlineMath' => [['$','$'], ['\\(','\\)']] },
|
15
|
+
'svg': { 'fontCache': 'global' }
|
12
16
|
}
|
13
17
|
}
|
14
18
|
end
|
@@ -27,8 +31,15 @@ module Jekyll::Spaceship
|
|
27
31
|
|
28
32
|
self.handled = true
|
29
33
|
|
30
|
-
|
31
|
-
|
34
|
+
# add mathjax config
|
35
|
+
cfg = config['config'].to_json
|
36
|
+
head.add_child("<script>MathJax=#{cfg}</script>")
|
37
|
+
|
38
|
+
# add mathjax dependencies
|
39
|
+
config['src'] = [config['src']] if config['src'].is_a? String
|
40
|
+
config['src'].each do |src|
|
41
|
+
head.add_child("<script src=\"#{src}\"></script>")
|
42
|
+
end
|
32
43
|
|
33
44
|
doc.to_html
|
34
45
|
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Jekyll::Spaceship
|
6
|
+
class MediaProcessor < Processor
|
7
|
+
def self.config
|
8
|
+
{
|
9
|
+
'default' => {
|
10
|
+
'id' => 'media-{id}',
|
11
|
+
'class' => 'media',
|
12
|
+
'width' => '100%',
|
13
|
+
'height' => 350,
|
14
|
+
'frameborder' => 0,
|
15
|
+
'style' => 'max-width: 600px;outline: none',
|
16
|
+
'allow' => 'encrypted-media; picture-in-picture'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_handle_markdown(content)
|
22
|
+
content = handle_normal_audio(content)
|
23
|
+
content = handle_normal_video(content)
|
24
|
+
content = handle_youtube(content)
|
25
|
+
content = handle_vimeo(content)
|
26
|
+
content = handle_dailymotion(content)
|
27
|
+
content = handle_spotify(content)
|
28
|
+
content = handle_soundcloud(content)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Examples:
|
32
|
+
# 
|
33
|
+
# 
|
34
|
+
def handle_normal_audio(content)
|
35
|
+
handle_media(content, {
|
36
|
+
media_type: 'audio',
|
37
|
+
host: '(https?:)?\\/\\/.*\\/',
|
38
|
+
id: '(.+?\\.(mp3|wav|ogg|mid|midi|aac|wma))',
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# Examples:
|
44
|
+
# 
|
45
|
+
# 
|
46
|
+
# 
|
47
|
+
def handle_normal_video(content)
|
48
|
+
handle_media(content, {
|
49
|
+
media_type: 'iframe',
|
50
|
+
host: '(https?:)?\\/\\/.*\\/',
|
51
|
+
id: '(.+?\\.(avi|mp4|webm|ogg|ogv|flv|mkv|mov|wmv|3gp|rmvb|asf))'
|
52
|
+
})
|
53
|
+
end
|
54
|
+
|
55
|
+
# Examples:
|
56
|
+
# 
|
57
|
+
# 
|
58
|
+
# 
|
59
|
+
def handle_youtube(content)
|
60
|
+
handle_media(content, {
|
61
|
+
media_type: 'iframe',
|
62
|
+
host: '(https?:)?\\/\\/.*youtu.*',
|
63
|
+
id: '(?<=\\?v\\=|embed\\/|\\.be\\/)([a-zA-Z0-9\\_\\-]+)',
|
64
|
+
base_url: "https://www.youtube.com/embed/"
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
68
|
+
# Examples:
|
69
|
+
# 
|
70
|
+
# 
|
71
|
+
def handle_vimeo(content)
|
72
|
+
handle_media(content, {
|
73
|
+
media_type: 'iframe',
|
74
|
+
host: '(https?:)?\\/\\/vimeo\\.com\\/',
|
75
|
+
id: '([0-9]+)',
|
76
|
+
base_url: "https://player.vimeo.com/video/"
|
77
|
+
})
|
78
|
+
end
|
79
|
+
|
80
|
+
# Examples:
|
81
|
+
# 
|
82
|
+
# 
|
83
|
+
def handle_dailymotion(content)
|
84
|
+
handle_media(content, {
|
85
|
+
media_type: 'iframe',
|
86
|
+
host: '(https?:)?\\/\\/.*dai.?ly.*',
|
87
|
+
id: '(?<=video\\/|\\/)([a-zA-Z0-9\\_\\-]+)',
|
88
|
+
base_url: "https://www.dailymotion.com/embed/video/"
|
89
|
+
})
|
90
|
+
end
|
91
|
+
|
92
|
+
# Examples:
|
93
|
+
# 
|
94
|
+
# 
|
95
|
+
def handle_spotify(content)
|
96
|
+
handle_media(content, {
|
97
|
+
media_type: 'iframe',
|
98
|
+
host: '(https?:)?\\/\\/open\\.spotify\\.com\\/track\\/',
|
99
|
+
id: '(?<=track\\/)([a-zA-Z0-9\\_\\-]+)',
|
100
|
+
base_url: "https://open.spotify.com/embed/track/",
|
101
|
+
height: 80
|
102
|
+
})
|
103
|
+
end
|
104
|
+
|
105
|
+
# Examples:
|
106
|
+
# 
|
107
|
+
def handle_soundcloud(content)
|
108
|
+
handle_media(content, {
|
109
|
+
media_type: 'iframe',
|
110
|
+
id_from: 'html',
|
111
|
+
host: '(https?:)?\\/\\/soundcloud\\.com\\/.+\\/[^\\?]+',
|
112
|
+
id: '(?<=soundcloud:\\/\\/sounds:)([0-9]+)',
|
113
|
+
base_url: "https://w.soundcloud.com/player/?url="\
|
114
|
+
"https%3A//api.soundcloud.com/tracks/",
|
115
|
+
height: 125,
|
116
|
+
})
|
117
|
+
end
|
118
|
+
|
119
|
+
def handle_media(content, data)
|
120
|
+
host = data[:host]
|
121
|
+
return content if content.sub(/#{host}/, '').nil?
|
122
|
+
|
123
|
+
media_type = data[:media_type]
|
124
|
+
base_url = data[:base_url]
|
125
|
+
id = data[:id_from] === 'html' ? '()' : data[:id]
|
126
|
+
url = "(#{host}#{id}\\S*)"
|
127
|
+
title = '("(.*)".*){0,1}'
|
128
|
+
|
129
|
+
# pre-handle reference-style links
|
130
|
+
regex = /(\[(.*)\]:\s*(#{url}\s*#{title}))/
|
131
|
+
content.scan regex do |match_data|
|
132
|
+
match = match_data[0]
|
133
|
+
ref_name = match_data[1]
|
134
|
+
ref_value = match_data[2]
|
135
|
+
content = content.gsub(match, '')
|
136
|
+
.gsub(/\!\[(.*)\]\s*\[#{ref_name}\]/,
|
137
|
+
"")
|
138
|
+
end
|
139
|
+
|
140
|
+
# handle inline-style links
|
141
|
+
regex = /(\!\[(.*)\]\(.*#{url}\s*#{title}\))/
|
142
|
+
content.scan regex do |match_data|
|
143
|
+
url = match_data[2]
|
144
|
+
id = data[:id_from] === 'html' \
|
145
|
+
? get_id_from_html(url, data[:id]) \
|
146
|
+
: match_data[4]
|
147
|
+
title = match_data[6]
|
148
|
+
qs = url.match(/(?<=\?)(\S*?)$/)
|
149
|
+
qs = Hash[URI.decode_www_form(qs.to_s)].reject do |k, v|
|
150
|
+
next true if v == id or v == ''
|
151
|
+
end
|
152
|
+
|
153
|
+
cfg = self.config['default'].clone
|
154
|
+
cfg['id'] = qs['id'] || cfg['id']
|
155
|
+
cfg['class'] = qs['class'] || cfg['class']
|
156
|
+
cfg['style'] = qs['style'] || cfg['style']
|
157
|
+
cfg['id'] = cfg['id'].gsub('{id}', id)
|
158
|
+
cfg['class'] = cfg['class'].gsub('{id}', id)
|
159
|
+
|
160
|
+
cfg['src'] = URI(base_url ? "#{base_url}#{id}" : url).tap do |v|
|
161
|
+
v.query = URI.encode_www_form(qs) if qs.size > 0
|
162
|
+
end
|
163
|
+
|
164
|
+
case media_type
|
165
|
+
when 'audio'
|
166
|
+
cfg['autoplay'] = qs['autoplay'] || data[:autoplay] || cfg['autoplay']
|
167
|
+
cfg['loop'] = qs['loop'] || data[:loop] || cfg['loop']
|
168
|
+
cfg['style'] += ';display: none;' if qs['hidden']
|
169
|
+
content = handle_audio(content, { target: match_data[0], cfg: cfg })
|
170
|
+
when 'iframe'
|
171
|
+
cfg['title'] = title
|
172
|
+
cfg['width'] = qs['width'] || data[:width] || cfg['width']
|
173
|
+
cfg['height'] = qs['height'] || data[:height] || cfg['height']
|
174
|
+
cfg['frameborder'] = qs['frameborder'] || cfg['frameborder']
|
175
|
+
cfg['allow'] ||= cfg['allow']
|
176
|
+
content = handle_iframe(content, { target: match_data[0], cfg: cfg })
|
177
|
+
end
|
178
|
+
self.handled = true
|
179
|
+
end
|
180
|
+
content
|
181
|
+
end
|
182
|
+
|
183
|
+
def handle_audio(content, data)
|
184
|
+
cfg = data[:cfg]
|
185
|
+
html = "<audio"\
|
186
|
+
" id=\"#{cfg['id']}\""\
|
187
|
+
" class=\"#{cfg['class']}\""\
|
188
|
+
" #{cfg['autoplay'] ? 'autoplay' : ''}"\
|
189
|
+
" #{cfg['loop'] ? 'loop' : ''}"\
|
190
|
+
" src=\"#{cfg['src']}\""\
|
191
|
+
" style=\"#{cfg['style']}\""\
|
192
|
+
" controls>" \
|
193
|
+
"<p> Your browser doesn't support HTML5 audio."\
|
194
|
+
" Here is a <a href=\"#{cfg['src']}\">link to download the audio</a>"\
|
195
|
+
"instead. </p>"\
|
196
|
+
"</audio>"
|
197
|
+
content.gsub(data[:target], html)
|
198
|
+
end
|
199
|
+
|
200
|
+
def handle_iframe(content, data)
|
201
|
+
cfg = data[:cfg]
|
202
|
+
html = "<iframe"\
|
203
|
+
" id=\"#{cfg['id']}\""\
|
204
|
+
" class=\"#{cfg['class']}\""\
|
205
|
+
" src=\"#{cfg['src']}\""\
|
206
|
+
" title=\"#{cfg['title']}\""\
|
207
|
+
" width=\"#{cfg['width']}\""\
|
208
|
+
" height=\"#{cfg['height']}\""\
|
209
|
+
" style=\"#{cfg['style']}\""\
|
210
|
+
" allow=\"#{cfg['allow']}\""\
|
211
|
+
" frameborder=\"#{cfg['frameborder']}\""\
|
212
|
+
" allowfullscreen>"\
|
213
|
+
"</iframe>"
|
214
|
+
content.gsub(data[:target], html)
|
215
|
+
end
|
216
|
+
|
217
|
+
def get_id_from_html(url, pattern)
|
218
|
+
id = ''
|
219
|
+
begin
|
220
|
+
url = 'https:' + url if url.start_with? '//'
|
221
|
+
res = Net::HTTP.get_response URI(url)
|
222
|
+
raise res.body unless res.is_a?(Net::HTTPSuccess)
|
223
|
+
res.body.match pattern do |match_data|
|
224
|
+
id = match_data[0]
|
225
|
+
break
|
226
|
+
end
|
227
|
+
rescue StandardError => msg
|
228
|
+
data = url
|
229
|
+
logger.log msg
|
230
|
+
end
|
231
|
+
id
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
@@ -62,18 +62,20 @@ module Jekyll::Spaceship
|
|
62
62
|
def handle_mermaid(code)
|
63
63
|
# encode to UTF-8
|
64
64
|
code = code.encode('UTF-8')
|
65
|
-
|
66
65
|
url = get_url(code)
|
67
66
|
|
68
67
|
# render mode
|
69
68
|
case self.config['mode']
|
70
69
|
when 'pre-fetch'
|
71
|
-
|
70
|
+
data = self.class.fetch_img_data(url)
|
71
|
+
end
|
72
|
+
if data.nil?
|
73
|
+
data = { 'type' => 'url', 'body' => url }
|
72
74
|
end
|
73
75
|
|
74
76
|
# return img tag
|
75
|
-
|
76
|
-
|
77
|
+
data['class'] = self.config['css']['class']
|
78
|
+
self.class.make_img_tag(data)
|
77
79
|
end
|
78
80
|
|
79
81
|
def get_url(code)
|
@@ -96,21 +98,5 @@ module Jekyll::Spaceship
|
|
96
98
|
raise "No supported src ! #{src}"
|
97
99
|
end
|
98
100
|
end
|
99
|
-
|
100
|
-
def get_mermaid_img_data(url)
|
101
|
-
data = ''
|
102
|
-
begin
|
103
|
-
res = Net::HTTP.get_response URI(url)
|
104
|
-
raise res.body unless res.is_a?(Net::HTTPSuccess)
|
105
|
-
data = Base64.encode64(res.body)
|
106
|
-
content_type = res.header['Content-Type']
|
107
|
-
raise 'Unknown content type!' if content_type.nil?
|
108
|
-
data = "data:#{content_type};base64, #{data}"
|
109
|
-
rescue StandardError => msg
|
110
|
-
data = url
|
111
|
-
logger.log msg
|
112
|
-
end
|
113
|
-
data
|
114
|
-
end
|
115
101
|
end
|
116
102
|
end
|
@@ -17,7 +17,7 @@ module Jekyll::Spaceship
|
|
17
17
|
'css' => {
|
18
18
|
'class' => 'plantuml'
|
19
19
|
},
|
20
|
-
'src' => 'http://www.plantuml.com/plantuml/
|
20
|
+
'src' => 'http://www.plantuml.com/plantuml/svg/'
|
21
21
|
}
|
22
22
|
end
|
23
23
|
|
@@ -59,18 +59,20 @@ module Jekyll::Spaceship
|
|
59
59
|
def handle_plantuml(code)
|
60
60
|
# wrap plantuml code
|
61
61
|
code = "@startuml#{code}@enduml".encode('UTF-8')
|
62
|
-
|
63
|
-
url = get_url(code)
|
62
|
+
url = self.get_url(code)
|
64
63
|
|
65
64
|
# render mode
|
66
65
|
case self.config['mode']
|
67
66
|
when 'pre-fetch'
|
68
|
-
|
67
|
+
data = self.class.fetch_img_data(url)
|
68
|
+
end
|
69
|
+
if data.nil?
|
70
|
+
data = { 'type' => 'url', 'body' => url }
|
69
71
|
end
|
70
72
|
|
71
73
|
# return img tag
|
72
|
-
|
73
|
-
|
74
|
+
data['class'] = self.config['css']['class']
|
75
|
+
self.class.make_img_tag(data)
|
74
76
|
end
|
75
77
|
|
76
78
|
def get_url(code)
|
@@ -87,21 +89,5 @@ module Jekyll::Spaceship
|
|
87
89
|
raise "No supported src ! #{src}"
|
88
90
|
end
|
89
91
|
end
|
90
|
-
|
91
|
-
def get_plantuml_img_data(url)
|
92
|
-
data = ''
|
93
|
-
begin
|
94
|
-
res = Net::HTTP.get_response URI(url)
|
95
|
-
raise res.body unless res.is_a?(Net::HTTPSuccess)
|
96
|
-
data = Base64.encode64(res.body)
|
97
|
-
content_type = res.header['Content-Type']
|
98
|
-
raise 'Unknown content type!' if content_type.nil?
|
99
|
-
data = "data:#{content_type};base64, #{data}"
|
100
|
-
rescue StandardError => msg
|
101
|
-
data = url
|
102
|
-
logger.log msg
|
103
|
-
end
|
104
|
-
data
|
105
|
-
end
|
106
92
|
end
|
107
93
|
end
|
@@ -5,6 +5,9 @@ require "nokogiri"
|
|
5
5
|
|
6
6
|
module Jekyll::Spaceship
|
7
7
|
class TableProcessor < Processor
|
8
|
+
ATTR_LIST_PATTERN = /((?<!\\)\{:(?:([A-Za-z]\S*):)?(.*?)(?<!\\)\})/
|
9
|
+
ATTR_LIST_REFS = {}
|
10
|
+
|
8
11
|
def on_handle_markdown(content)
|
9
12
|
# pre-handle reference-style links
|
10
13
|
references = {}
|
@@ -16,7 +19,9 @@ module Jekyll::Spaceship
|
|
16
19
|
if references.size > 0
|
17
20
|
content.scan(/[^\n]*(?<!\\)\|[^\n]*/) do |result|
|
18
21
|
references.each do |key, val|
|
19
|
-
replace = result.gsub(
|
22
|
+
replace = result.gsub(
|
23
|
+
/\[([^\n\]]*?)\]\s*\[#{key}\]/,
|
24
|
+
"[\1](#{val})")
|
20
25
|
next if result == replace
|
21
26
|
content = content.gsub(result, replace)
|
22
27
|
end
|
@@ -42,6 +47,19 @@ module Jekyll::Spaceship
|
|
42
47
|
next if result == replace
|
43
48
|
content = content.gsub(result, replace)
|
44
49
|
end
|
50
|
+
|
51
|
+
# pre-handle attribute list (AL)
|
52
|
+
ATTR_LIST_REFS.clear()
|
53
|
+
content.scan(ATTR_LIST_PATTERN) do |result|
|
54
|
+
ref = result[1]
|
55
|
+
list = result[2]
|
56
|
+
next if ref.nil?
|
57
|
+
if ATTR_LIST_REFS.has_key? ref
|
58
|
+
ATTR_LIST_REFS[ref] += list
|
59
|
+
else
|
60
|
+
ATTR_LIST_REFS[ref] = list
|
61
|
+
end
|
62
|
+
end
|
45
63
|
content
|
46
64
|
end
|
47
65
|
|
@@ -69,6 +87,7 @@ module Jekyll::Spaceship
|
|
69
87
|
handle_multi_rows(data)
|
70
88
|
handle_text_align(data)
|
71
89
|
handle_rowspan(data)
|
90
|
+
handle_attr_list(data)
|
72
91
|
end
|
73
92
|
end
|
74
93
|
rows.each do |row|
|
@@ -161,7 +180,7 @@ module Jekyll::Spaceship
|
|
161
180
|
if scope.table.multi_row_cells != cells and scope.table.multi_row_start
|
162
181
|
for i in 0...scope.table.multi_row_cells.count do
|
163
182
|
multi_row_cell = scope.table.multi_row_cells[i]
|
164
|
-
multi_row_cell.inner_html += "<br
|
183
|
+
multi_row_cell.inner_html += "\n<br>\n#{cells[i].inner_html}"
|
165
184
|
end
|
166
185
|
row.remove
|
167
186
|
end
|
@@ -186,7 +205,7 @@ module Jekyll::Spaceship
|
|
186
205
|
span_cell = scope.table.span_row_cells[scope.row.col_index]
|
187
206
|
if span_cell and cell.content.match(/^\s*\^{2}/)
|
188
207
|
cell.content = cell.content.gsub(/^\s*\^{2}/, '')
|
189
|
-
span_cell.inner_html += "<br
|
208
|
+
span_cell.inner_html += "\n<br>\n#{cell.inner_html}"
|
190
209
|
rowspan = span_cell.get_attribute('rowspan') || 1
|
191
210
|
rowspan = rowspan.to_i + 1
|
192
211
|
span_cell.set_attribute('rowspan', "#{rowspan}")
|
@@ -235,6 +254,52 @@ module Jekyll::Spaceship
|
|
235
254
|
cell.set_attribute('style', style)
|
236
255
|
end
|
237
256
|
|
257
|
+
# Examples:
|
258
|
+
# {:ref-name: .cls1 title="hello" }
|
259
|
+
# {: #id ref-name data="world" }
|
260
|
+
# {: #id title="hello" }
|
261
|
+
# {: .cls style="color: #333" }
|
262
|
+
def handle_attr_list(data)
|
263
|
+
cell = data.cell
|
264
|
+
content = cell.inner_html
|
265
|
+
# inline attribute list(IAL) handler
|
266
|
+
ial_handler = ->(list) do
|
267
|
+
list.scan(/(\S+)=("|')(.*?)\2|(\S+)/) do |attr|
|
268
|
+
key = attr[0]
|
269
|
+
val = attr[2]
|
270
|
+
single = attr[3]
|
271
|
+
if !key.nil?
|
272
|
+
val = (cell.get_attribute(key) || '') + val
|
273
|
+
cell.set_attribute(key, val)
|
274
|
+
elsif !single.nil?
|
275
|
+
if single.start_with? '#'
|
276
|
+
key = 'id'
|
277
|
+
val = single[1..-1]
|
278
|
+
elsif single.start_with? '.'
|
279
|
+
key = 'class'
|
280
|
+
val = cell.get_attribute(key) || ''
|
281
|
+
val += (val.size.zero? ? '' : ' ') + single[1..-1]
|
282
|
+
elsif ATTR_LIST_REFS.has_key? single
|
283
|
+
ial_handler.call ATTR_LIST_REFS[single]
|
284
|
+
end
|
285
|
+
unless key.nil?
|
286
|
+
cell.set_attribute(key, val)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
# handle attribute list
|
292
|
+
content.scan(ATTR_LIST_PATTERN) do |result|
|
293
|
+
ref = result[1]
|
294
|
+
list = result[2]
|
295
|
+
# handle inline attribute list
|
296
|
+
ial_handler.call list if ref.nil?
|
297
|
+
# remove attr_list
|
298
|
+
content = content.sub(result[0], '')
|
299
|
+
end
|
300
|
+
cell.inner_html = content
|
301
|
+
end
|
302
|
+
|
238
303
|
def handle_format(data)
|
239
304
|
cell = data.cell
|
240
305
|
cvter = self.converter('markdown')
|
@@ -242,6 +307,8 @@ module Jekyll::Spaceship
|
|
242
307
|
content = cell.inner_html
|
243
308
|
.gsub(/(?<!\\)\|/, '\\|')
|
244
309
|
.gsub(/^\s+|\s+$/, '')
|
310
|
+
.gsub(/</, '<')
|
311
|
+
.gsub(/>/, '>')
|
245
312
|
content = cvter.convert(content)
|
246
313
|
content = Nokogiri::HTML.fragment(content)
|
247
314
|
if content.children.first&.name == 'p'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-spaceship
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jeffreytse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- ".codeclimate.yml"
|
125
125
|
- ".github/FUNDING.yml"
|
126
126
|
- ".gitignore"
|
127
|
+
- ".rspec"
|
127
128
|
- ".travis.yml"
|
128
129
|
- Gemfile
|
129
130
|
- LICENSE.txt
|
@@ -140,11 +141,11 @@ files:
|
|
140
141
|
- lib/jekyll-spaceship/processors/element-processor.rb
|
141
142
|
- lib/jekyll-spaceship/processors/emoji-processor.rb
|
142
143
|
- lib/jekyll-spaceship/processors/mathjax-processor.rb
|
144
|
+
- lib/jekyll-spaceship/processors/media-processor.rb
|
143
145
|
- lib/jekyll-spaceship/processors/mermaid-processor.rb
|
144
146
|
- lib/jekyll-spaceship/processors/plantuml-processor.rb
|
145
147
|
- lib/jekyll-spaceship/processors/polyfill-processor.rb
|
146
148
|
- lib/jekyll-spaceship/processors/table-processor.rb
|
147
|
-
- lib/jekyll-spaceship/processors/video-processor.rb
|
148
149
|
- lib/jekyll-spaceship/utils/.keep
|
149
150
|
- lib/jekyll-spaceship/version.rb
|
150
151
|
- logos/jekyll-spaceship-logo.png
|
@@ -169,10 +170,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
170
|
- !ruby/object:Gem::Version
|
170
171
|
version: '0'
|
171
172
|
requirements: []
|
172
|
-
|
173
|
-
rubygems_version: 2.7.7
|
173
|
+
rubygems_version: 3.0.8
|
174
174
|
signing_key:
|
175
175
|
specification_version: 4
|
176
176
|
summary: A Jekyll plugin to provide powerful supports for table, mathjax, plantuml,
|
177
|
-
mermaid, emoji, video, youtube, vimeo, dailymotion,
|
177
|
+
mermaid, emoji, video, audio, youtube, vimeo, dailymotion, spotify, soundcloud,
|
178
|
+
etc.
|
178
179
|
test_files: []
|
@@ -1,139 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
module Jekyll::Spaceship
|
6
|
-
class VideoProcessor < Processor
|
7
|
-
def self.config
|
8
|
-
{
|
9
|
-
'default' => {
|
10
|
-
'id' => 'video-{id}',
|
11
|
-
'class' => 'video',
|
12
|
-
'width' => '100%',
|
13
|
-
'height' => 350,
|
14
|
-
'border' => 0,
|
15
|
-
'style' => 'max-width: 600px',
|
16
|
-
'allow' => 'encrypted-media; picture-in-picture',
|
17
|
-
}
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
def on_handle_markdown(content)
|
22
|
-
content = handle_normal_video(content)
|
23
|
-
content = handle_youtube(content)
|
24
|
-
content = handle_vimeo(content)
|
25
|
-
content = handle_dailymotion(content)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Examples:
|
29
|
-
# 
|
30
|
-
# 
|
31
|
-
# 
|
32
|
-
def handle_normal_video(content)
|
33
|
-
handle_video(content, {
|
34
|
-
host: '(https?:)?\\/\\/.*\\/',
|
35
|
-
id: '(.+?\\.(avi|mp4|webm|ogg|ogv|flv|mkv|mov|wmv|3gp|rmvb|asf))',
|
36
|
-
})
|
37
|
-
end
|
38
|
-
|
39
|
-
# Examples:
|
40
|
-
# 
|
41
|
-
# 
|
42
|
-
# 
|
43
|
-
def handle_youtube(content)
|
44
|
-
handle_video(content, {
|
45
|
-
host: '(https?:)?\\/\\/.*youtu.*',
|
46
|
-
id: '(?<=\\?v\\=|embed\\/|\\.be\\/)([a-zA-Z0-9\\_\\-]+)',
|
47
|
-
iframe_url: "https://www.youtube.com/embed/"
|
48
|
-
})
|
49
|
-
end
|
50
|
-
|
51
|
-
# Examples:
|
52
|
-
# 
|
53
|
-
# 
|
54
|
-
def handle_vimeo(content)
|
55
|
-
handle_video(content, {
|
56
|
-
host: '(https?:)?\\/\\/vimeo\\.com\\/',
|
57
|
-
id: '([0-9]+)',
|
58
|
-
iframe_url: "https://player.vimeo.com/video/"
|
59
|
-
})
|
60
|
-
end
|
61
|
-
|
62
|
-
# Examples:
|
63
|
-
# 
|
64
|
-
# 
|
65
|
-
def handle_dailymotion(content)
|
66
|
-
handle_video(content, {
|
67
|
-
host: '(https?:)?\\/\\/.*dai.?ly.*',
|
68
|
-
id: '(?<=video\\/|\\/)([a-zA-Z0-9\\_\\-]+)',
|
69
|
-
iframe_url: "https://www.dailymotion.com/embed/video/"
|
70
|
-
})
|
71
|
-
end
|
72
|
-
|
73
|
-
def handle_video(content, data)
|
74
|
-
host = data[:host]
|
75
|
-
return content if content.sub(/#{host}/, '').nil?
|
76
|
-
|
77
|
-
iframe_url = data[:iframe_url]
|
78
|
-
id = data[:id]
|
79
|
-
url = "(#{host}#{id}\\S*)"
|
80
|
-
title = '("(.*)".*){0,1}'
|
81
|
-
|
82
|
-
# pre-handle reference-style links
|
83
|
-
regex = /(\[(.*)\]:\s*(#{url}\s*#{title}))/
|
84
|
-
content.scan regex do |match_data|
|
85
|
-
match = match_data[0]
|
86
|
-
ref_name = match_data[1]
|
87
|
-
ref_value = match_data[2]
|
88
|
-
content = content.gsub(match, '')
|
89
|
-
.gsub(/\!\[(.*)\]\s*\[#{ref_name}\]/,
|
90
|
-
"")
|
91
|
-
end
|
92
|
-
|
93
|
-
# handle inline-style links
|
94
|
-
regex = /(\!\[(.*)\]\(.*#{url}\s*#{title}\))/
|
95
|
-
content.scan regex do |match_data|
|
96
|
-
url = match_data[2]
|
97
|
-
id = match_data[4]
|
98
|
-
title = match_data[6]
|
99
|
-
qs = url.match(/(?<=\?)(\S*?)$/)
|
100
|
-
qs = Hash[URI.decode_www_form(qs.to_s)].reject do |k, v|
|
101
|
-
next true if v == id or v == ''
|
102
|
-
end
|
103
|
-
|
104
|
-
default = self.config['default']
|
105
|
-
css_id = qs['id'] || default['id']
|
106
|
-
css_class = qs['class'] || default['class']
|
107
|
-
width = qs['width'] || data[:width] || default['width']
|
108
|
-
height = qs['height'] || data[:height] || default['height']
|
109
|
-
frameborder = qs['frameborder'] || default['border']
|
110
|
-
style = qs['style'] || default['style']
|
111
|
-
allow = qs['allow'] || default['allow']
|
112
|
-
|
113
|
-
css_id = css_id.gsub('{id}', id)
|
114
|
-
css_class = css_class.gsub('{id}', id)
|
115
|
-
|
116
|
-
url = URI(iframe_url ? "#{iframe_url}#{id}" : url).tap do |v|
|
117
|
-
v.query = URI.encode_www_form(qs) if qs.size > 0
|
118
|
-
end
|
119
|
-
|
120
|
-
html = "<iframe"\
|
121
|
-
" id=\"#{css_id}\""\
|
122
|
-
" class=\"#{css_class}\""\
|
123
|
-
" src=\"#{url}\""\
|
124
|
-
" title=\"#{title}\""\
|
125
|
-
" width=\"#{width}\""\
|
126
|
-
" height=\"#{height}\""\
|
127
|
-
" style=\"#{style}\""\
|
128
|
-
" allow=\"#{allow}\""\
|
129
|
-
" frameborder=\"#{frameborder}\""\
|
130
|
-
" allowfullscreen>" \
|
131
|
-
"</iframe>"
|
132
|
-
|
133
|
-
content = content.gsub(match_data[0], html)
|
134
|
-
self.handled = true
|
135
|
-
end
|
136
|
-
content
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|