jekyll-spaceship 0.6.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8df3e5c04610d7f6ae766303a8b884e1b3bd0047f72ac489275dd26d133d392a
4
- data.tar.gz: '0728453eaace46c6d88aa0395f1d17ae88c17a727aa3be9b10236c222fc3d85e'
3
+ metadata.gz: 26f4057b47af49da27acf7f6d6b26851e9094b70f4c2a939270d8fbb0c49272f
4
+ data.tar.gz: 64a5c8f08a467de5a67a24d89dba5785d48e2d68add11a8acb10e4199e01922c
5
5
  SHA512:
6
- metadata.gz: 1b5e65d14b80d87ebb06b9e3c5cc7c71f6d654940d58034ab314d232d5ff6614bd3b22649259d3658690b5e94b5c4e6983214a0b3e4bdd91cd03e7702901a51e
7
- data.tar.gz: f7a171a023c65ceb729ade833fe7193b05000aa24483c1bd0bc6201c28df47f69d503aa2612a866aba1627fc86626f63d38b7db41b8d75a616805b14f1d71fff
6
+ metadata.gz: decab1852e2c7f1dc439eee47805ca18d1192657b7ebb2c707737a031734e376f971d1b5e22e3ea435308caf010ad5f90d55fa13353170822cee5c51c0496b3b
7
+ data.tar.gz: 9d11c7b8437a5047b52370ca49de6f84360a80dcb0021f687b0b817644095ab2086b0157a6b2587bc9041906b698005556d444d8f05719b106bc65ec9b361912
data/README.md CHANGED
@@ -105,16 +105,18 @@ Spaceship is a minimalistic, powerful and extremely customizable [Jekyll](https:
105
105
  - [2.1 Performance Optimization](#21-performance-optimization)
106
106
  - [2.2 How to use?](#22-how-to-use)
107
107
  - [3. PlantUML Usage](#3-plantuml-usage)
108
- - [4. Video Usage](#4-video-usage)
109
- - [4.1 Youtube Usage](#youtube-usage)
110
- - [4.2 Vimeo Usage](#vimeo-usage)
111
- - [4.3 DailyMotion Usage](#dailymotion-usage)
112
- - [4.4 General Video Usage](#general-video-usage)
113
- - [5. Hybrid HTML with Markdown](#5-hybrid-html-with-markdown)
114
- - [6. Markdown Polyfill](#6-markdown-polyfill)
115
- - [6.1 Escape Ordered List](#escape-ordered-list)
116
- - [7. Emoji Usage](#7-emoji-usage)
117
- - [7.1 Emoji Customizing](#71-emoji-customizing)
108
+ - [4. Mermaid Usage](#4-mermaid-usage)
109
+ - [5. Video Usage](#5-video-usage)
110
+ - [5.1 Youtube Usage](#youtube-usage)
111
+ - [5.2 Vimeo Usage](#vimeo-usage)
112
+ - [5.3 DailyMotion Usage](#dailymotion-usage)
113
+ - [5.4 General Video Usage](#general-video-usage)
114
+ - [6. Hybrid HTML with Markdown](#6-hybrid-html-with-markdown)
115
+ - [7. Markdown Polyfill](#7-markdown-polyfill)
116
+ - [7.1 Escape Ordered List](#71-escape-ordered-list)
117
+ - [8. Emoji Usage](#8-emoji-usage)
118
+ - [8.1 Emoji Customizing](#81-emoji-customizing)
119
+ - [9. Modifying Element Usage](#9-modifying-element-usage)
118
120
  - [Credits](#credits)
119
121
  - [Contributing](#contributing)
120
122
  - [License](#license)
@@ -147,13 +149,16 @@ This plugin runs with the following configuration options by default. Alternativ
147
149
  ```yml
148
150
  # Where things are
149
151
  jekyll-spaceship:
152
+ # default enabled processors
150
153
  processors:
151
154
  - table-processor
152
155
  - mathjax-processor
153
156
  - plantuml-processor
157
+ - mermaid-processor
154
158
  - polyfill-processor
155
159
  - video-processor
156
160
  - emoji-processor
161
+ - element-processor
157
162
  mathjax-processor:
158
163
  src: //cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML
159
164
  config:
@@ -162,8 +167,35 @@ jekyll-spaceship:
162
167
  - ['$','$']
163
168
  - ['\(','\)']
164
169
  plantuml-processor:
170
+ mode: default # mode value 'pre-fetch' for fetch image at building stage
171
+ css:
172
+ class: plantuml
173
+ syntax:
174
+ code: 'plantuml!'
175
+ custom: ['@startuml', '@enduml']
165
176
  src: http://www.plantuml.com/plantuml/png/
177
+ mermaid-processor:
178
+ mode: default # mode value 'pre-fetch' for fetch image at building stage
179
+ css:
180
+ class: mermaid
181
+ syntax:
182
+ code: 'mermaid!'
183
+ custom: ['@startmermaid', '@endmermaid']
184
+ config:
185
+ theme: default
186
+ src: https://mermaid.ink/svg/
187
+ video-processor:
188
+ default:
189
+ id: 'video-{id}'
190
+ class: 'video'
191
+ width: '100%'
192
+ height: 350
193
+ border: 0
194
+ style: 'max-width: 600px'
195
+ allow: 'encrypted-media; picture-in-picture'
166
196
  emoji-processor:
197
+ css:
198
+ class: emoji
167
199
  src: https://github.githubassets.com/images/icons/emoji/
168
200
  ```
169
201
 
@@ -544,13 +576,13 @@ Code above would be parsed as:
544
576
  - class diagram,
545
577
  - activity diagram,
546
578
  - component diagram,
547
- - state diagram
579
+ - state diagram,
548
580
  - object diagram
549
581
 
550
582
  There are two ways to create a diagram in your Jekyll blog page:
551
583
 
552
- ````markdown
553
- ```plantuml
584
+ ````
585
+ ```plantuml!
554
586
  Bob -> Alice : hello world
555
587
  ```
556
588
  ````
@@ -567,7 +599,48 @@ Code above would be parsed as:
567
599
 
568
600
  ![PlantUML Diagram](https://user-images.githubusercontent.com/9413601/82813883-9180b300-9ec8-11ea-8778-f450e0056938.png)
569
601
 
570
- ### 4. Video Usage
602
+ ### 4. Mermaid Usage
603
+
604
+ [Mermaid](https://mermaid-js.github.io/) is a Javascript based diagramming and charting tool. It generates diagrams flowcharts and more, using markdown-inspired text for ease and speed.
605
+
606
+ It allows to quickly write:
607
+
608
+ - flow chart,
609
+ - pie chart,
610
+ - sequence diagram,
611
+ - class diagram,
612
+ - state diagram,
613
+ - entity relationship diagram,
614
+ - user journey,
615
+ - gantt
616
+
617
+ There are two ways to create a diagram in your Jekyll blog page:
618
+
619
+ ````
620
+ ```mermaid!
621
+ pie title Pets adopted by volunteers
622
+ "Dogs" : 386
623
+ "Cats" : 85
624
+ "Rats" : 35
625
+ ```
626
+ ````
627
+
628
+ or
629
+
630
+ ```markdown
631
+ @startmermaid
632
+ pie title Pets adopted by volunteers
633
+ "Dogs" : 386
634
+ "Cats" : 85
635
+ "Rats" : 35
636
+ @endmermaid
637
+ ```
638
+
639
+ Code above would be parsed as:
640
+
641
+ ![Mermaid Diagram](https://user-images.githubusercontent.com/9413601/85282355-2e317300-b4be-11ea-9c30-8f9d61540d14.png)
642
+
643
+ ### 5. Video Usage
571
644
 
572
645
  How often did you find yourself googling "**How to embed a video in markdown?**"
573
646
 
@@ -601,9 +674,7 @@ the link as below:
601
674
 
602
675
  ```markdown
603
676
  ![](https://www.youtube.com/watch?v=Ptk_1Dc2iPY?width=800&height=500)
604
- ```
605
677
 
606
- ```markdown
607
678
  ![](https://www.dailymotion.com/video/x7tfyq3?width=100%&height=400&autoplay=1)
608
679
  ```
609
680
 
@@ -611,9 +682,7 @@ the link as below:
611
682
 
612
683
  ```markdown
613
684
  ![](https://www.youtube.com/watch?v=Ptk_1Dc2iPY)
614
- ```
615
685
 
616
- ```markdown
617
686
  ![](//www.youtube.com/watch?v=Ptk_1Dc2iPY?width=800&height=500)
618
687
  ```
619
688
 
@@ -621,9 +690,7 @@ the link as below:
621
690
 
622
691
  ```markdown
623
692
  ![](https://vimeo.com/263856289)
624
- ```
625
693
 
626
- ```markdown
627
694
  ![](https://vimeo.com/263856289?width=500&height=320)
628
695
  ```
629
696
 
@@ -631,9 +698,7 @@ the link as below:
631
698
 
632
699
  ```markdown
633
700
  ![](https://www.dailymotion.com/video/x7tfyq3)
634
- ```
635
701
 
636
- ```markdown
637
702
  ![](https://dai.ly/x7tgcev?width=100%&height=400)
638
703
  ```
639
704
 
@@ -641,18 +706,14 @@ the link as below:
641
706
 
642
707
  ```markdown
643
708
  ![](//www.html5rocks.com/en/tutorials/video/basics/devstories.webm)
644
- ```
645
709
 
646
- ```markdown
647
710
  ![](//techslides.com/demos/sample-videos/small.ogv?allow=autoplay)
648
- ```
649
711
 
650
- ```markdown
651
712
  ![](//techslides.com/demos/sample-videos/small.mp4?width=400)
652
713
  ```
653
714
 
654
715
 
655
- ### 5. Hybrid HTML with Markdown
716
+ ### 6. Hybrid HTML with Markdown
656
717
 
657
718
  As markdown is not only a lightweight markup language with plain-text-formatting syntax, but also an easy-to-read and easy-to-write plain text format, so writing a hybrid HTML with markdown is an awesome choice.
658
719
 
@@ -686,7 +747,7 @@ Bob -> Alice : hello
686
747
  </script>
687
748
  ```
688
749
 
689
- ### 6. Markdown Polyfill
750
+ ### 7. Markdown Polyfill
690
751
 
691
752
  It allows us to polyfill features for extending markdown syntax.
692
753
 
@@ -694,7 +755,7 @@ It allows us to polyfill features for extending markdown syntax.
694
755
 
695
756
  - Escape ordered list
696
757
 
697
- #### Escape Ordered List
758
+ #### 7.1 Escape Ordered List
698
759
 
699
760
  A backslash at begin to escape the ordered list.
700
761
 
@@ -728,7 +789,7 @@ Escaped:
728
789
  10. List item Cafe.
729
790
  ```
730
791
 
731
- ### 7. Emoji Usage
792
+ ### 8. Emoji Usage
732
793
  GitHub-flavored emoji images and names would allow emojifying content such as: it's raining :cat:s and :dog:s!
733
794
 
734
795
  Noted that emoji images are served from the GitHub.com CDN, with a base URL of [https://github.githubassets.com](https://github.githubassets.com), which results in emoji image URLs like [https://github.githubassets.com/images/icons/emoji/unicode/1f604.png](https://github.githubassets.com/images/icons/emoji/unicode/1f604.png).
@@ -743,7 +804,7 @@ I give this plugin two :+1:!
743
804
 
744
805
  I give this plugin two :+1:!
745
806
 
746
- #### 7.1 Emoji Customizing
807
+ #### 8.1 Emoji Customizing
747
808
 
748
809
  If you'd like to serve emoji images locally, or use a custom emoji source, you can specify so in your `_config.yml` file:
749
810
 
@@ -755,6 +816,93 @@ jekyll-spaceship:
755
816
 
756
817
  See the [Gemoji](https://github.com/github/gemoji) documentation for generating image files.
757
818
 
819
+ ### 9. Modifying Element Usage
820
+
821
+ It allows us to modify elements via `CSS3 selectors`. Through it you can easily
822
+ modify the attributes of an element tag, replace the children nodes and so on,
823
+ it's very flexible, but here is example usage for modifying a document:
824
+
825
+ ```yml
826
+ # Here is a comprehensive example
827
+ jekyll-spaceship:
828
+ element-processor:
829
+ css:
830
+ - a: '<h1>Test</h1>' # Replace all `a` tags (String Style)
831
+ - ['a.link1', 'a.link2']: # Replace all `a.link1`, `a.link2` tags (Hash Style)
832
+ name: img # Replace element tag name
833
+ props: # Replace element properties
834
+ title: Good image # Add a title attribute
835
+ src: ['(^.*$)', '\0?a=123'] # Add query string to src attribute by regex pattern
836
+ style: # Add style attribute (Hash Style)
837
+ color: red
838
+ font-size: '1.2em'
839
+ children: # Add children to the element
840
+ - # First empty for adding after the last child node
841
+ - "<span>Google</span>" # First child node (String Style)
842
+ - # Middle empty for wrapping the children nodes
843
+ - name: span # Second child node (Hash Style)
844
+ props:
845
+ prop1: "1" # Custom property1
846
+ prop2: "2" # Custom property2
847
+ prop3: "3" # Custom property3
848
+ children: # Add nested chidren nodes
849
+ - "<span>Jekyll</span>" # First child node (String Style)
850
+ - name: span # Second child node (Hash Style)
851
+ props: # Add attributes to child node (Hash Style)
852
+ prop1: "a"
853
+ prop2: "b"
854
+ prop3: "c"
855
+ children: "<b>Yap!</b>" # Add children nodes (String Style)
856
+ - # Last empty for adding before the first child node
857
+ - a.link: '<a href="//t.com">Link</a>' # Replace all `a.link` tags (String Style)
858
+ - 'h1#title': # Replace `h1#title` tags (Hash Style)
859
+ children: I'm a title! # Replace inner html to new text
860
+ ```
861
+
862
+ #### Example 1
863
+
864
+ Automatically adds a `target="_blank" rel="noopener noreferrer"` attribute to all external links in Jekyll's content.
865
+
866
+ ```yml
867
+ jekyll-spaceship:
868
+ element-processor:
869
+ css:
870
+ - a: # Replce all `a` tags
871
+ props:
872
+ class: ['(^.*$)', '\0 ext-link'] # Add `ext-link` to class by regex pattern
873
+ target: _blank # Replace `target` value to `_blank`
874
+ rel: noopener noreferrer # Replace `rel` value to `noopener noreferrer`
875
+ ```
876
+
877
+ #### Example 2
878
+
879
+ Automatically adds `loading="lazy"` to `img` and `iframe` tags to natively load lazily.
880
+ [Browser support](https://caniuse.com/#feat=loading-lazy-attr) is growing. If a browser does not support the `loading` attribute, it will load the resource just like it would normally.
881
+
882
+ ```yml
883
+ jekyll-spaceship:
884
+ element-processor:
885
+ css:
886
+ - a: # Replce all `a` tags
887
+ props: #
888
+ loading: lazy # Replace `lading` value to `lazy`
889
+ ```
890
+
891
+ In case you want to prevent loading some images/iframes lazily, add
892
+ `loading="eager"` to their tags. This might be useful to prevent flickering of
893
+ images during navigation (e.g. the site's logo).
894
+
895
+ See the following examples to prevent lazy loading.
896
+
897
+ ```yml
898
+ jekyll-spaceship:
899
+ element-processor:
900
+ css:
901
+ - a: # Replce all `a` tags
902
+ props: #
903
+ loading: eager # Replace `loading` value to `eager`
904
+ ```
905
+
758
906
 
759
907
  ## Credits
760
908
 
@@ -762,6 +910,9 @@ See the [Gemoji](https://github.com/github/gemoji) documentation for generating
762
910
  - [MultiMarkdown](https://fletcher.github.io/MultiMarkdown-6) - Lightweight markup processor to produce HTML, LaTeX, and more.
763
911
  - [markdown-it-multimd-table](https://github.com/RedBug312/markdown-it-multimd-table) - Multimarkdown table syntax plugin for markdown-it markdown parser.
764
912
  - [jmoji](https://github.com/jekyll/jemoji) - GitHub-flavored emoji plugin for Jekyll.
913
+ - [jekyll-target-blank](https://github.com/keithmifsud/jekyll-target-blank) - Automatically opens external links in a new browser for Jekyll Pages, Posts and Docs.
914
+ - [jekyll-loading-lazy](https://github.com/gildesmarais/jekyll-loading-lazy) - Automatically adds loading="lazy" to img and iframe tags to natively load lazily.
915
+ - [mermaid](https://github.com/mermaid-js/mermaid) - Generation of diagram and flowchart from text in a similar manner as markdown.
765
916
 
766
917
  ## Contributing
767
918
 
@@ -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, emoji, video, youtube, vimeo, dailymotion, etc."
12
+ spec.summary = "A Jekyll plugin to provide powerful supports for table, mathjax, plantuml, mermaid, emoji, video, youtube, vimeo, dailymotion, etc."
13
13
  spec.homepage = "https://github.com/jeffreytse/jekyll-spaceship"
14
14
  spec.license = "MIT"
15
15
 
@@ -8,5 +8,5 @@ require 'jekyll-spaceship/cores/register'
8
8
 
9
9
  module Jekyll::Spaceship
10
10
  Logger.display_info
11
- Config.load
11
+ Config.load_config
12
12
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
4
-
5
3
  module Jekyll::Spaceship
6
4
  class Config
7
5
  CONFIG_NAME = 'jekyll-spaceship'
@@ -10,9 +8,11 @@ module Jekyll::Spaceship
10
8
  'table-processor',
11
9
  'mathjax-processor',
12
10
  'plantuml-processor',
11
+ 'mermaid-processor',
13
12
  'polyfill-processor',
14
13
  'video-processor',
15
- 'emoji-processor'
14
+ 'emoji-processor',
15
+ 'element-processor'
16
16
  ]
17
17
  }
18
18
 
@@ -32,15 +32,14 @@ module Jekyll::Spaceship
32
32
  end
33
33
 
34
34
  def self.store(section, default)
35
- return if @@store[section].nil?
36
35
  return @@store[section] if default.nil?
37
- @@store[section] = deep_merge(@@store[section], default)
36
+ @@store[section] = deep_merge(default, @@store[section])
38
37
  end
39
38
 
40
- def self.load(filename = '_config.yml')
39
+ def self.load(config = {})
41
40
  config = deep_merge(
42
41
  { CONFIG_NAME => DEFAULT_CONFIG },
43
- YAML.load_file(File.expand_path(filename))
42
+ config
44
43
  )[CONFIG_NAME]
45
44
  @@store = config
46
45
  self.use_processors(config)
@@ -51,5 +50,12 @@ module Jekyll::Spaceship
51
50
  Register.use processor
52
51
  end
53
52
  end
53
+
54
+ def self.load_config
55
+ # post load site config for `group :jekyll_plugin`
56
+ Jekyll::Hooks.register :site, :after_init do |site|
57
+ self.load(site.config)
58
+ end
59
+ end
54
60
  end
55
61
  end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+
5
+ module Jekyll::Spaceship
6
+ class ElementProcessor < Processor
7
+ priority :lowest
8
+
9
+ def self.config
10
+ { 'css' => [] }
11
+ end
12
+
13
+ def on_handle_html(content)
14
+ return content if config['css'].size.zero?
15
+
16
+ # use nokogiri to parse html content
17
+ doc = Nokogiri::HTML(content)
18
+
19
+ # handle each css pattern
20
+ config['css'].each do |data|
21
+ data.each do |key, val|
22
+ key = [key] if key.kind_of? String
23
+ key.each do |pattern|
24
+ nodes = doc.css(pattern)
25
+ nodes.each do |element|
26
+ handle_css_pattern({
27
+ :doc => doc,
28
+ :element => element,
29
+ :data => val
30
+ })
31
+ end
32
+ self.handled = true
33
+ end
34
+ end
35
+ end
36
+
37
+ doc.to_html
38
+ end
39
+
40
+ def handle_css_pattern(data)
41
+ doc = data[:doc]
42
+ element = data[:element]
43
+ data = data[:data]
44
+
45
+ if data.kind_of? String
46
+ element.replace Nokogiri::HTML.fragment(data)
47
+ elsif data.kind_of? Hash
48
+ # set name
49
+ element.name = data['name'] unless data['name'].nil?
50
+
51
+ # set props
52
+ data['props']&.each do |prop, val|
53
+ next element.remove_attribute if val.nil?
54
+ if val.kind_of? Array
55
+ next if val.size != 2
56
+ v = element[prop]
57
+ v = '' if v.nil?
58
+ val = v.sub(/#{val[0]}/, val[1])
59
+ elsif val.kind_of? Hash
60
+ result = []
61
+ val.each { |k, v| result.push "#{k}: #{v}" }
62
+ val = result.join(";")
63
+ end
64
+ element.set_attribute(prop, val)
65
+ end
66
+
67
+ # processing children
68
+ return unless data.has_key?('children')
69
+ return element.inner_html = "" if data['children'].nil?
70
+ children = self.create_children({
71
+ :doc => doc,
72
+ :data => data['children']
73
+ })
74
+
75
+ # replace whole inner html
76
+ unless data['children'].kind_of? Array
77
+ return element.inner_html = children
78
+ end
79
+
80
+ if element.children.size.zero?
81
+ return element.inner_html = children
82
+ end
83
+
84
+ index = data['children'].index(nil)
85
+ if index.nil?
86
+ return element.inner_html = children
87
+ end
88
+
89
+ # insert to the end of children
90
+ if index == 0
91
+ return element.children.last.after(children)
92
+ end
93
+
94
+ # insert to the begin of children
95
+ rindex = data['children'].rindex { |item| !item.nil? }
96
+ if index == rindex + 1
97
+ return element.children.first.before children
98
+ end
99
+
100
+ # wrap the children
101
+ element.children.first.before children[0..index]
102
+ element.children.last.after children[index..children.size]
103
+ end
104
+ end
105
+
106
+ def create_children(data)
107
+ doc = data[:doc]
108
+ data = data[:data]
109
+ root = Nokogiri::HTML.fragment("")
110
+
111
+ data = [data] unless data.kind_of? Array
112
+ data.each do |child_data|
113
+ node = self.create_element({
114
+ :doc => doc,
115
+ :data => child_data
116
+ })
117
+ next if node.nil?
118
+ unless child_data['children'].nil?
119
+ node.children = self.create_children({
120
+ :doc => doc,
121
+ :data => child_data['children']
122
+ })
123
+ end
124
+ root.add_child node
125
+ end
126
+ root.children
127
+ end
128
+
129
+ def create_element(data)
130
+ doc = data[:doc]
131
+ data = data[:data]
132
+
133
+ return if data.nil?
134
+ return Nokogiri::HTML.fragment(data) if data.kind_of? String
135
+ return if data['name'].nil?
136
+
137
+ # create node
138
+ node = doc.create_element(data['name'])
139
+
140
+ # set props
141
+ data['props']&.each do |prop, val|
142
+ if val.kind_of? Hash
143
+ result = []
144
+ val.each { |k, v| result.push "#{k}: #{v}" }
145
+ val = result.join(";")
146
+ end
147
+ node.set_attribute(prop, val)
148
+ end
149
+ node
150
+ end
151
+ end
152
+ end
@@ -7,7 +7,12 @@ require 'gemoji'
7
7
  module Jekyll::Spaceship
8
8
  class EmojiProcessor < Processor
9
9
  def self.config
10
- { 'src' => 'https://github.githubassets.com/images/icons/emoji/' }
10
+ {
11
+ 'css' => {
12
+ 'class' => 'emoji'
13
+ },
14
+ 'src' => 'https://github.githubassets.com/images/icons/emoji/'
15
+ }
11
16
  end
12
17
 
13
18
  def on_handle_html(content)
@@ -22,7 +27,7 @@ module Jekyll::Spaceship
22
27
 
23
28
  content = content.gsub(
24
29
  /(?<!\=")\s*:#{emoji_name}:\s*(?!"\s)/,
25
- "<img class=\"emoji\""\
30
+ "<img class=\"\""\
26
31
  " title=\":#{emoji.name}:\""\
27
32
  " alt=\":#{emoji.name}:\""\
28
33
  " raw=\"#{emoji.raw}\""\
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "base64"
5
+
6
+ module Jekyll::Spaceship
7
+ class MermaidProcessor < Processor
8
+ exclude :none
9
+
10
+ def self.config
11
+ {
12
+ 'mode' => 'default',
13
+ 'syntax' => {
14
+ 'code' => 'mermaid!',
15
+ 'custom' => ['@startmermaid', '@endmermaid']
16
+ },
17
+ 'css' => {
18
+ 'class' => 'mermaid'
19
+ },
20
+ 'config': {
21
+ 'theme' => 'default'
22
+ },
23
+ 'src' => 'https://mermaid.ink/svg/'
24
+ }
25
+ end
26
+
27
+ def on_handle_markdown(content)
28
+ # match custom mermaid block and code block
29
+ syntax = self.config['syntax']
30
+ code_name = syntax['code']
31
+ custom = syntax['custom'][-2, 2]
32
+
33
+ patterns = [
34
+ /((`{3,})\s*#{code_name}((?:.|\n)*?)\2)/,
35
+ /((?<!\\)(#{custom[0]})((?:.|\n)*?)(?<!\\)(#{custom[1]}))/
36
+ ]
37
+
38
+ patterns.each do |pattern|
39
+ content = handle_mermaid_block(pattern, content)
40
+ end
41
+
42
+ # handle escape custom mermaid block
43
+ content.gsub(/\\(#{custom[0]}|#{custom[1]})/, '\1')
44
+ end
45
+
46
+ def handle_mermaid_block(pattern, content)
47
+ content.scan pattern do |match|
48
+ match = match.select { |m| not m.nil? }
49
+ block = match[0]
50
+ code = match[2]
51
+
52
+ self.handled = true
53
+
54
+ content = content.gsub(
55
+ block,
56
+ handle_mermaid(code)
57
+ )
58
+ end
59
+ content
60
+ end
61
+
62
+ def handle_mermaid(code)
63
+ # encode to UTF-8
64
+ code = code.encode('UTF-8')
65
+
66
+ url = get_url(code)
67
+
68
+ # render mode
69
+ case self.config['mode']
70
+ when 'pre-fetch'
71
+ url = self.get_mermaid_img_data(url)
72
+ end
73
+
74
+ # return img tag
75
+ css_class = self.config['css']['class']
76
+ "<img class=\"#{css_class}\" src=\"#{url}\">"
77
+ end
78
+
79
+ def get_url(code)
80
+ src = self.config['src']
81
+
82
+ # wrap code
83
+ code = {
84
+ 'code' => code.gsub(/^\s*|\s*$/, ''),
85
+ 'mermaid' => config['config']
86
+ }.to_json
87
+
88
+ # set default method
89
+ src += '{code}' if src.match(/\{.*\}/).nil?
90
+
91
+ # encode to base64 string
92
+ if src.include?('{code}')
93
+ code = Base64.urlsafe_encode64(code, padding: false)
94
+ return src.gsub('{code}', code)
95
+ else
96
+ raise "No supported src ! #{src}"
97
+ end
98
+ 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
+ end
116
+ end
@@ -7,23 +7,37 @@ module Jekyll::Spaceship
7
7
  class PlantumlProcessor < Processor
8
8
  exclude :none
9
9
 
10
- PLANTUML_PATTERNS = [
11
- /(\\?(@startuml)((?:.|\n)*?)@enduml)/,
12
- /((`{3,})\s*plantuml((?:.|\n)*?)\2)/
13
- ]
14
-
15
10
  def self.config
16
- { 'src' => 'http://www.plantuml.com/plantuml/png/' }
11
+ {
12
+ 'mode' => 'default',
13
+ 'syntax' => {
14
+ 'code' => 'plantuml!',
15
+ 'custom' => ['@startuml', '@enduml']
16
+ },
17
+ 'css' => {
18
+ 'class' => 'plantuml'
19
+ },
20
+ 'src' => 'http://www.plantuml.com/plantuml/png/'
21
+ }
17
22
  end
18
23
 
19
24
  def on_handle_markdown(content)
20
- # match default plantuml block and code block
21
- PLANTUML_PATTERNS.each do |pattern|
25
+ # match custom plantuml block and code block
26
+ syntax = self.config['syntax']
27
+ code_name = syntax['code']
28
+ custom = syntax['custom'][-2, 2]
29
+
30
+ patterns = [
31
+ /((`{3,})\s*#{code_name}((?:.|\n)*?)\2)/,
32
+ /((?<!\\)(#{custom[0]})((?:.|\n)*?)(?<!\\)(#{custom[1]}))/
33
+ ]
34
+
35
+ patterns.each do |pattern|
22
36
  content = handle_plantuml_block(pattern, content)
23
37
  end
24
38
 
25
- # handle escape default plantuml block
26
- content.gsub(/\\(@startuml|@enduml)/, '\1')
39
+ # handle escape custom plantuml block
40
+ content.gsub(/\\(#{custom[0]}|#{custom[1]})/, '\1')
27
41
  end
28
42
 
29
43
  def handle_plantuml_block(pattern, content)
@@ -32,11 +46,6 @@ module Jekyll::Spaceship
32
46
  block = match[0]
33
47
  code = match[2]
34
48
 
35
- # skip escape default plantuml block
36
- if block.match(/(^\\@startuml|\\@enduml$)/)
37
- next
38
- end
39
-
40
49
  self.handled = true
41
50
 
42
51
  content = content.gsub(
@@ -51,21 +60,43 @@ module Jekyll::Spaceship
51
60
  # wrap plantuml code
52
61
  code = "@startuml#{code}@enduml".encode('UTF-8')
53
62
 
54
- # encode to hex string
55
- code = '~h' + code.unpack("H*").first
56
- data = self.get_plantuml_img_data(code)
63
+ url = get_url(code)
64
+
65
+ # render mode
66
+ case self.config['mode']
67
+ when 'pre-fetch'
68
+ url = self.get_plantuml_img_data(url)
69
+ end
57
70
 
58
71
  # return img tag
59
- "<img class=\"plantuml\" src=\"#{data}\">"
72
+ css_class = self.config['css']['class']
73
+ "<img class=\"#{css_class}\" src=\"#{url}\">"
74
+ end
75
+
76
+ def get_url(code)
77
+ src = self.config['src']
78
+
79
+ # set default method
80
+ src += '{hexcode}' if src.match(/\{.*\}/).nil?
81
+
82
+ # encode to hex string
83
+ if src.include?('{hexcode}')
84
+ code = '~h' + code.unpack("H*").first
85
+ return src.gsub('{hexcode}', code)
86
+ else
87
+ raise "No supported src ! #{src}"
88
+ end
60
89
  end
61
90
 
62
- def get_plantuml_img_data(code)
91
+ def get_plantuml_img_data(url)
63
92
  data = ''
64
- url = "#{config['src']}#{code}"
65
93
  begin
66
- data = Net::HTTP.get URI(url)
67
- data = Base64.encode64(data)
68
- data = "data:image/png;base64, #{data}"
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}"
69
100
  rescue StandardError => msg
70
101
  data = url
71
102
  logger.log msg
@@ -4,6 +4,20 @@ require 'uri'
4
4
 
5
5
  module Jekyll::Spaceship
6
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
+
7
21
  def on_handle_markdown(content)
8
22
  content = handle_normal_video(content)
9
23
  content = handle_youtube(content)
@@ -87,13 +101,17 @@ module Jekyll::Spaceship
87
101
  next true if v == id or v == ''
88
102
  end
89
103
 
90
- css_id = qs['id'] || "video-#{id}"
91
- css_class = qs['class'] || 'video'
92
- width = qs['width'] || data[:width] || "100%"
93
- height = qs['height'] || data[:height] || 350
94
- frameborder = qs['frameborder'] || 0
95
- style = qs['style'] || 'max-width: 600px'
96
- allow = qs['allow'] || "encrypted-media; picture-in-picture"
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.gsub('{id}', id)
114
+ css_class.gsub('{id}', id)
97
115
 
98
116
  url = URI(iframe_url ? "#{iframe_url}#{id}" : url).tap do |v|
99
117
  v.query = URI.encode_www_form(qs) if qs.size > 0
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module Spaceship
5
- VERSION = "0.6.3"
5
+ VERSION = "0.8.0"
6
6
  end
7
7
  end
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.6.3
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jeffreytse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-13 00:00:00.000000000 Z
11
+ date: 2020-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -137,8 +137,10 @@ files:
137
137
  - lib/jekyll-spaceship/cores/processor.rb
138
138
  - lib/jekyll-spaceship/cores/register.rb
139
139
  - lib/jekyll-spaceship/cores/type.rb
140
+ - lib/jekyll-spaceship/processors/element-processor.rb
140
141
  - lib/jekyll-spaceship/processors/emoji-processor.rb
141
142
  - lib/jekyll-spaceship/processors/mathjax-processor.rb
143
+ - lib/jekyll-spaceship/processors/mermaid-processor.rb
142
144
  - lib/jekyll-spaceship/processors/plantuml-processor.rb
143
145
  - lib/jekyll-spaceship/processors/polyfill-processor.rb
144
146
  - lib/jekyll-spaceship/processors/table-processor.rb
@@ -172,5 +174,5 @@ rubygems_version: 2.7.7
172
174
  signing_key:
173
175
  specification_version: 4
174
176
  summary: A Jekyll plugin to provide powerful supports for table, mathjax, plantuml,
175
- emoji, video, youtube, vimeo, dailymotion, etc.
177
+ mermaid, emoji, video, youtube, vimeo, dailymotion, etc.
176
178
  test_files: []