jekyll-spaceship 0.6.3 → 0.8.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 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: []