jekyll-gfm-admonitions 1.1.3 → 1.2.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: fe52d1b378cd72599412354a594b5d99664cad7c52cca706508ae274f47e8896
4
- data.tar.gz: 322883e94a7da73b034e5d9196dcdd6a89dc5fbf0f4bfd645aea5025d9f5f8c5
3
+ metadata.gz: af82aad7f5de88ea4b015e47a3856f47568ee3ffe38439d69fdac7ef3a969f05
4
+ data.tar.gz: 58afb6c8e56f72188268889b9d66baa92d49481be558de5353f9fbea2925f9a4
5
5
  SHA512:
6
- metadata.gz: 1e763423e5b814c237f41893e51e8149916a7e0732a277429c45f26ae18ad3a1acae02cfb14c3730073d05e2110dc5280c7479bae551dd3bd92352e40439e20a
7
- data.tar.gz: a2d25051eb3740e119e6a61c205ca1d35f533ba3b4ebd3b4396564873d863b2965522a9474f00d5f72671c93396de7ba63d5faa8af877766f1752bb4d9aaf205
6
+ metadata.gz: 6b2c5adaba2c7b98a0fd9ea820ba595a90e9ad0701320314e47610931c5ca12bbb4f7099b4a20f36dd9d9fac3b8517303714361ee92c0a340188dc7c4cf4e1cf
7
+ data.tar.gz: 49e77ba137e187beee3bfe54492f77709dd6617bc6ac6aaa43c9528ae20cda311ffcbca2e498bc1a91a17976b49b7289a9b7c56fdd356f8e79e476d63232aeb8
data/LICENSE.txt CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Robin De Schepper
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- - The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Robin De Schepper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ - The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,190 +1,198 @@
1
- # GitHub Flavored Admonitions
2
-
3
- A Jekyll plugin to render GitHub-flavored admonitions in your Jekyll sites.
4
- This plugin allows you to use GitHub-flavored markdown syntax to create stylish admonition
5
- blocks for notes, warnings, tips, cautions, and important messages.
6
-
7
- ## Features
8
-
9
- * Admonitions
10
- * Admonition titles
11
- * Jekyll support
12
- * GitHub Pages support
13
-
14
- ## Supported Admonitions
15
-
16
- The following admonitions are supported:
17
-
18
- | **Type** | **Markdown** |
19
- |---------------|-----------------------|
20
- | Note | `> [!NOTE]` |
21
- | Tip | `> [!TIP]` |
22
- | Important | `> [!IMPORTANT]` |
23
- | Warning | `> [!WARNING]` |
24
- | Caution | `> [!CAUTION]` |
25
-
26
-
27
- ### Example Usage
28
-
29
- To use admonitions in your markdown files, simply add the following syntax:
30
-
31
- ```markdown
32
- > [!NOTE]
33
- > Highlights information that users should take into account, even when skimming.
34
- > And supports multi-line text.
35
-
36
- > [!TIP]
37
- > Optional information to help a user be more successful.
38
-
39
- > [!IMPORTANT]
40
- > Crucial information necessary for users to succeed.
41
-
42
- > [!WARNING]
43
- > Critical content demanding immediate
44
- > user attention due to potential risks.
45
-
46
- > [!CAUTION]
47
- > Negative potential consequences of an action.
48
- > Opportunity to provide more context.
49
- ```
50
-
51
- > [!NOTE]
52
- > Highlights information that users should take into account, even when skimming.
53
- > And supports multi-line text.
54
-
55
- > [!TIP]
56
- > Optional information to help a user be more successful.
57
-
58
- > [!IMPORTANT]
59
- > Crucial information necessary for users to succeed.
60
-
61
- > [!WARNING]
62
- > Critical content demanding immediate
63
- > user attention due to potential risks.
64
-
65
- > [!CAUTION]
66
- > Negative potential consequences of an action.
67
- > Opportunity to provide more context.
68
-
69
- #### Custom titles
70
-
71
- Custom admonition titles are supported:
72
-
73
- > [!TIP] My own title
74
- > Fancy!
75
-
76
- > [!NOTE]
77
- > GFM itself does not support this syntax, so this will only wokr in your
78
- > build output, but not on your GitHub rendered READMEs etc.
79
-
80
-
81
- ## Installation
82
-
83
- To install the plugin, add it to your Jekyll project's `Gemfile`:
84
-
85
- ```ruby
86
- group :jekyll_plugins do
87
-
88
- # Other plugins go here ...
89
-
90
- # ... Add this line:
91
- gem "jekyll-gfm-admonitions"
92
- end
93
- ```
94
-
95
- Then run:
96
-
97
- ```bash
98
- bundle install
99
- ```
100
-
101
- ### Configuring Jekyll
102
-
103
- Next, you need to enable the plugin in your Jekyll configuration file (`_config.yml`):
104
-
105
- ```yaml
106
- plugins:
107
- - jekyll-gfm-admonitions
108
- ```
109
-
110
- Then, during `build`/`serve`, you should see logs similar to:
111
-
112
- ```
113
- GFMA: Converted adminitions in 36 file(s).
114
- GFMA: Injecting admonition CSS in 36 page(s).
115
- ```
116
-
117
- More details are available by passing the `--verbose` flag to your `jekyll` command.
118
-
119
- ## When using GitHub Pages
120
-
121
- To enable custom plugins in your Jekyll build for GitHub Pages, you need to use GitHub
122
- Actions (GHA) to build and deploy your Jekyll site. For detailed instructions on setting
123
- up GitHub Actions for your Jekyll project, please follow this link:
124
- [GitHub Actions Setup for Jekyll](https://jekyllrb.com/docs/continuous-integration/github-actions/).
125
-
126
- After following the steps you will have to set up a minimal valid Jekyll project.
127
-
128
- ### Add a `_config.yml`
129
-
130
- ```yaml
131
- # Site settings
132
- title: Your Project Title
133
- repository: your-username/your-repository
134
- description: >-
135
- A description of your project
136
-
137
- markdown: GFM
138
- plugins:
139
- - jekyll-gfm-admonitions
140
- - jekyll-optional-front-matter
141
-
142
- exclude:
143
- - "**/*.ts" # Exclude source code files!
144
- - "**/*.js"
145
- - "*.ts" # Also those in the root directory!
146
- - "*.js"
147
- - "*.json" # Don't forget about assets!
148
- - node_modules/ # And large vendored directories
149
- # And these ignore all the artifacts the build produces:
150
- - .sass-cache/
151
- - .jekyll-cache/
152
- - gemfiles/
153
- - Gemfile
154
- - Gemfile.lock
155
- - vendor/bundle/
156
- - vendor/cache/
157
- - vendor/gems/
158
- - vendor/ruby/
159
- ```
160
-
161
- > [!CAUTION]
162
- >
163
- > For private repositories, make sure you exclude your source code files from the Jekyll
164
- > build, or they might be publicly deployed! Also exclude large vendored package
165
- > directories such as `node_modules/`.
166
-
167
- ### Add a `Gemfile`:
168
-
169
- ```ruby
170
- source 'https://rubygems.org'
171
-
172
- gem 'jekyll'
173
- group :jekyll_plugins do
174
- gem 'jekyll-gfm-admonitions'
175
- gem 'jekyll-optional-front-matter'
176
- gem 'github-pages'
177
- end
178
- gem 'jekyll-remote-theme'
179
- ```
180
-
181
- ## License
182
-
183
- This project is licensed under the MIT License. See the [LICENSE.txt](LICENSE.txt) file
184
- for details.
185
-
186
- ## Contributing
187
-
188
-
189
- > [!TIP]
1
+ # GitHub Flavored Admonitions
2
+
3
+ A Jekyll plugin to render GitHub-flavored admonitions in your Jekyll sites.
4
+ This plugin allows you to use GitHub-flavored markdown syntax to create stylish admonition
5
+ blocks for notes, warnings, tips, cautions, and important messages.
6
+
7
+ ## Features
8
+
9
+ * Admonitions
10
+ * Admonition titles
11
+ * Jekyll support
12
+ * GitHub Pages support
13
+
14
+ ## Supported Admonitions
15
+
16
+ The following admonitions are supported:
17
+
18
+ | **Type** | **Markdown** |
19
+ |---------------|-----------------------|
20
+ | Note | `> [!NOTE]` |
21
+ | Tip | `> [!TIP]` |
22
+ | Important | `> [!IMPORTANT]` |
23
+ | Warning | `> [!WARNING]` |
24
+ | Caution | `> [!CAUTION]` |
25
+
26
+
27
+ ### Example Usage
28
+
29
+ To use admonitions in your markdown files, simply add the following syntax:
30
+
31
+ ```markdown
32
+ > [!NOTE]
33
+ > Highlights information that users should take into account, even when skimming.
34
+ > And supports multi-line text.
35
+
36
+ > [!TIP]
37
+ > Optional information to help a user be more successful.
38
+
39
+ > [!IMPORTANT]
40
+ > Crucial information necessary for users to succeed.
41
+
42
+ > [!WARNING]
43
+ > Critical content demanding immediate
44
+ > user attention due to potential risks.
45
+
46
+ > [!CAUTION]
47
+ > Negative potential consequences of an action.
48
+ > Opportunity to provide more context.
49
+ ```
50
+
51
+ > [!NOTE]
52
+ > Highlights information that users should take into account, even when skimming.
53
+ > And supports multi-line text.
54
+
55
+ > [!TIP]
56
+ > Optional information to help a user be more successful.
57
+
58
+ > [!IMPORTANT]
59
+ > Crucial information necessary for users to succeed.
60
+
61
+ > [!WARNING]
62
+ > Critical content demanding immediate
63
+ > user attention due to potential risks.
64
+
65
+ > [!CAUTION]
66
+ > Negative potential consequences of an action.
67
+ > Opportunity to provide more context.
68
+
69
+ #### Custom titles
70
+
71
+ Custom admonition titles are supported:
72
+
73
+ ```markdown
74
+ > [!TIP] My own title
75
+ > Fancy!
76
+ ```
77
+
78
+ > [!TIP] My own title
79
+ > Fancy!
80
+
81
+ > [!NOTE]
82
+ > GFM itself does not support this syntax, so this will only work in your
83
+ > [build output](https://helveg.github.io/jekyll-gfm-admonitions/#custom-titles),
84
+ > but not on your
85
+ > [GitHub rendered README](https://github.com/Helveg/jekyll-gfm-admonitions/blob/main/README.md#custom-titles)s
86
+ > etc.
87
+
88
+
89
+ ## Installation
90
+
91
+ To install the plugin, add it to your Jekyll project's `Gemfile`:
92
+
93
+ ```ruby
94
+ group :jekyll_plugins do
95
+
96
+ # Other plugins go here ...
97
+
98
+ # ... Add this line:
99
+ gem "jekyll-gfm-admonitions"
100
+ end
101
+ ```
102
+
103
+ Then run:
104
+
105
+ ```bash
106
+ bundle install
107
+ ```
108
+
109
+ ### Configuring Jekyll
110
+
111
+ Next, you need to enable the plugin in your Jekyll configuration file (`_config.yml`):
112
+
113
+ ```yaml
114
+ plugins:
115
+ - jekyll-gfm-admonitions
116
+ ```
117
+
118
+ Then, during `build`/`serve`, you should see logs similar to:
119
+
120
+ ```
121
+ GFMA: Converted adminitions in 36 file(s).
122
+ GFMA: Injecting admonition CSS in 36 page(s).
123
+ ```
124
+
125
+ More details are available by passing the `--verbose` flag to your `jekyll` command.
126
+
127
+ ## When using GitHub Pages
128
+
129
+ To enable custom plugins in your Jekyll build for GitHub Pages, you need to use GitHub
130
+ Actions (GHA) to build and deploy your Jekyll site. For detailed instructions on setting
131
+ up GitHub Actions for your Jekyll project, please follow this link:
132
+ [GitHub Actions Setup for Jekyll](https://jekyllrb.com/docs/continuous-integration/github-actions/).
133
+
134
+ After following the steps you will have to set up a minimal valid Jekyll project.
135
+
136
+ ### Add a `_config.yml`
137
+
138
+ ```yaml
139
+ # Site settings
140
+ title: Your Project Title
141
+ repository: your-username/your-repository
142
+ description: >-
143
+ A description of your project
144
+
145
+ markdown: GFM
146
+ plugins:
147
+ - jekyll-gfm-admonitions
148
+ - jekyll-optional-front-matter
149
+
150
+ exclude:
151
+ - "**/*.ts" # Exclude source code files!
152
+ - "**/*.js"
153
+ - "*.ts" # Also those in the root directory!
154
+ - "*.js"
155
+ - "*.json" # Don't forget about assets!
156
+ - node_modules/ # And large vendored directories
157
+ # And these ignore all the artifacts the build produces:
158
+ - .sass-cache/
159
+ - .jekyll-cache/
160
+ - gemfiles/
161
+ - Gemfile
162
+ - Gemfile.lock
163
+ - vendor/bundle/
164
+ - vendor/cache/
165
+ - vendor/gems/
166
+ - vendor/ruby/
167
+ ```
168
+
169
+ > [!CAUTION]
170
+ >
171
+ > For private repositories, make sure you exclude your source code files from the Jekyll
172
+ > build, or they might be publicly deployed! Also exclude large vendored package
173
+ > directories such as `node_modules/`.
174
+
175
+ ### Add a `Gemfile`:
176
+
177
+ ```ruby
178
+ source 'https://rubygems.org'
179
+
180
+ gem 'jekyll'
181
+ group :jekyll_plugins do
182
+ gem 'jekyll-gfm-admonitions'
183
+ gem 'jekyll-optional-front-matter'
184
+ gem 'github-pages'
185
+ end
186
+ gem 'jekyll-remote-theme'
187
+ ```
188
+
189
+ ## License
190
+
191
+ This project is licensed under the MIT License. See the [LICENSE.txt](LICENSE.txt) file
192
+ for details.
193
+
194
+ ## Contributing
195
+
196
+
197
+ > [!TIP]
190
198
  > Contributions are welcome! Please feel free to submit issues or pull requests.
@@ -1,69 +1,69 @@
1
- .markdown-alert {
2
- padding: 0.5rem 1rem;
3
- margin-bottom: 1rem;
4
- color: inherit;
5
- border-left: .25em solid #30363d;
6
- }
7
-
8
- .markdown-alert > :first-child {
9
- margin-top: 0;
10
- }
11
-
12
- .markdown-alert > :last-child {
13
- margin-bottom: 0;
14
- }
15
-
16
- .markdown-alert .markdown-alert-title {
17
- display: flex;
18
- font-weight: 500;
19
- align-items: center;
20
- line-height: 1;
21
- }
22
-
23
- .markdown-alert svg {
24
- margin-right: 0.5rem !important;
25
- }
26
-
27
- .markdown-alert svg path {
28
- fill: currentColor;
29
- }
30
-
31
- .markdown-alert.markdown-alert-note {
32
- border-left-color: #4493f8;
33
- }
34
-
35
- .markdown-alert.markdown-alert-note .markdown-alert-title {
36
- color: #4493f8;
37
- }
38
-
39
- .markdown-alert.markdown-alert-important {
40
- border-left-color: #ab7df8;
41
- }
42
-
43
- .markdown-alert.markdown-alert-important .markdown-alert-title {
44
- color: #ab7df8;
45
- }
46
-
47
- .markdown-alert.markdown-alert-warning {
48
- border-left-color: #9e6a03;
49
- }
50
-
51
- .markdown-alert.markdown-alert-warning .markdown-alert-title {
52
- color: #d29922;
53
- }
54
-
55
- .markdown-alert.markdown-alert-tip {
56
- border-left-color: #238636;
57
- }
58
-
59
- .markdown-alert.markdown-alert-tip .markdown-alert-title {
60
- color: #3fb950;
61
- }
62
-
63
- .markdown-alert.markdown-alert-caution {
64
- border-left-color: #da3633;
65
- }
66
-
67
- .markdown-alert.markdown-alert-caution .markdown-alert-title {
68
- color: #f85149;
1
+ .markdown-alert {
2
+ padding: 0.5rem 1rem;
3
+ margin-bottom: 1rem;
4
+ color: inherit;
5
+ border-left: .25em solid #30363d;
6
+ }
7
+
8
+ .markdown-alert > :first-child {
9
+ margin-top: 0;
10
+ }
11
+
12
+ .markdown-alert > :last-child {
13
+ margin-bottom: 0;
14
+ }
15
+
16
+ .markdown-alert .markdown-alert-title {
17
+ display: flex;
18
+ font-weight: 500;
19
+ align-items: center;
20
+ line-height: 1;
21
+ }
22
+
23
+ .markdown-alert svg {
24
+ margin-right: 0.5rem !important;
25
+ }
26
+
27
+ .markdown-alert svg path {
28
+ fill: currentColor;
29
+ }
30
+
31
+ .markdown-alert.markdown-alert-note {
32
+ border-left-color: #4493f8;
33
+ }
34
+
35
+ .markdown-alert.markdown-alert-note .markdown-alert-title {
36
+ color: #4493f8;
37
+ }
38
+
39
+ .markdown-alert.markdown-alert-important {
40
+ border-left-color: #ab7df8;
41
+ }
42
+
43
+ .markdown-alert.markdown-alert-important .markdown-alert-title {
44
+ color: #ab7df8;
45
+ }
46
+
47
+ .markdown-alert.markdown-alert-warning {
48
+ border-left-color: #9e6a03;
49
+ }
50
+
51
+ .markdown-alert.markdown-alert-warning .markdown-alert-title {
52
+ color: #d29922;
53
+ }
54
+
55
+ .markdown-alert.markdown-alert-tip {
56
+ border-left-color: #238636;
57
+ }
58
+
59
+ .markdown-alert.markdown-alert-tip .markdown-alert-title {
60
+ color: #3fb950;
61
+ }
62
+
63
+ .markdown-alert.markdown-alert-caution {
64
+ border-left-color: #da3633;
65
+ }
66
+
67
+ .markdown-alert.markdown-alert-caution .markdown-alert-title {
68
+ color: #f85149;
69
69
  }
@@ -1,141 +1,143 @@
1
- # frozen_string_literal: true
2
-
3
- require 'octicons'
4
- require 'cssminify'
5
- require 'liquid/template'
6
-
7
- ADMONITION_ICONS = {
8
- 'important' => 'report',
9
- 'note' => 'info',
10
- 'tip' => 'light-bulb',
11
- 'warning' => 'alert',
12
- 'caution' => 'stop'
13
- }.freeze
14
-
15
- # JekyllGFMAdmonitions is a module that provides functionality to process and
16
- # convert GitHub-flavored markdown admonitions into HTML within Jekyll.
17
- module JekyllGFMAdmonitions
18
- # GFMAdmonitionConverter is a Jekyll generator that converts custom
19
- # admonition blocks in markdown (e.g., `> [!IMPORTANT]`) into styled HTML
20
- # alert boxes with icons.
21
- #
22
- # This generator processes both posts and pages, replacing admonition
23
- # syntax with HTML markup that includes appropriate iconography and CSS styling.
24
- class GFMAdmonitionConverter < Jekyll::Generator
25
- safe true
26
- priority :lowest
27
- @admonition_pages = []
28
-
29
- class << self
30
- attr_reader :admonition_pages
31
- end
32
-
33
-
34
- def generate(site)
35
- init_converter(site)
36
- process_posts(site)
37
- process_pages(site)
38
- Jekyll.logger.info 'GFMA:', 'Converted adminitions in' \
39
- " #{self.class.admonition_pages.length} file(s)."
40
- end
41
-
42
- def init_converter(site)
43
- @markdown = site.converters.find { |c| c.is_a?(Jekyll::Converters::Markdown) }
44
- return if @markdown
45
-
46
- raise 'Markdown converter not found. Please ensure that you have a markdown' \
47
- ' converter configured in your Jekyll site.'
48
- end
49
-
50
- def process_posts(site)
51
- site.posts.docs.each do |doc|
52
- Jekyll.logger.debug 'GFMA:', "Processing post '#{doc.path}' (#{doc.content.length} characters)."
53
- process_doc_content(doc)
54
- end
55
- end
56
-
57
- def process_pages(site)
58
- site.pages.each do |page|
59
- Jekyll.logger.debug 'GFMA:', "Processing page '#{page.path}' (#{page.content.length} characters)."
60
- process_doc_content(page)
61
- end
62
- end
63
-
64
- def process_doc_content(doc)
65
- original_content = doc.content.dup
66
- process_doc(doc)
67
-
68
- return unless doc.content != original_content
69
-
70
- # Store a reference to all the pages we modified, to inject the CSS post render
71
- # (otherwise GitHub Pages sanitizes the CSS into plaintext)
72
- self.class.admonition_pages << doc
73
- end
74
-
75
- def process_doc(doc)
76
- # Return early if content is empty
77
- return if doc.content.empty?
78
-
79
- # If the content is frozen, we need to duplicate it so that we can modify it
80
- doc.content = doc.content.dup unless doc.content.frozen?
81
-
82
- code_blocks = []
83
- # Temporarily replace code blocks by a tag, so that we don't process any admonitions
84
- # inside of code blocks.
85
- doc.content.gsub!(/(?:^|\n)(?<!>)\s*```.*?```/m) do |match|
86
- code_blocks << match
87
- "```{{CODE_BLOCK_#{code_blocks.length - 1}}}```"
88
- end
89
-
90
- convert_admonitions(doc)
91
-
92
- # Put the code blocks back in place
93
- doc.content.gsub!(/```\{\{CODE_BLOCK_(\d+)}}```/) do
94
- code_blocks[::Regexp.last_match(1).to_i]
95
- end
96
- end
97
-
98
- def convert_admonitions(doc)
99
- doc.content.gsub!(/^(\s*)>\s*\[!(IMPORTANT|NOTE|WARNING|TIP|CAUTION)\]([^\n]*)\n((?:\1\s*>\s*[^\n]*(?:\n|$))(?:(?!\s*>\s*\[!)\1\s*>\s*[^\n]*(?:\n|$))*)/) do
100
- initial_indent = ::Regexp.last_match(1)
101
- type = ::Regexp.last_match(2).downcase
102
- title = ::Regexp.last_match(3).strip.empty? ? type.capitalize : ::Regexp.last_match(3).strip
103
- text = ::Regexp.last_match(4).gsub(/^#{Regexp.escape(initial_indent)}\s*>\s*/, '').strip
104
-
105
- icon = Octicons::Octicon.new(ADMONITION_ICONS[type]).to_svg
106
- admonition_html(type, title, text, icon)
107
- end
108
-
109
- # 🛠 Ensure a blank line exists after each admonition block to prevent Markdown parsing issues.
110
- doc.content.gsub!(/(<\/div>)(?!\n\n)/, "\\1\n\n")
111
- end
112
-
113
- def admonition_html(type, title, text, icon)
114
- "<div class='markdown-alert markdown-alert-#{type}'>" \
115
- "<p class='markdown-alert-title'>#{icon} #{title}</p>" \
116
- "#{@markdown.convert(text)}" \
117
- "</div>"
118
- end
119
- end
120
-
121
- # Insert the minified CSS before the closing head tag of all pages we put admonitions on
122
- Jekyll::Hooks.register :site, :post_render do
123
- Jekyll.logger.info 'GFMA:', "Inserting admonition CSS in #{GFMAdmonitionConverter.admonition_pages.length} page(s)."
124
-
125
- GFMAdmonitionConverter.admonition_pages.each do |page|
126
- Jekyll.logger.debug 'GFMA:', "Appending admonition style to '#{page.path}'."
127
- css = File.read(File.expand_path('../assets/admonitions.css', __dir__))
128
-
129
- page.output.gsub!(%r{<head>(.*?)</head>}m) do |match|
130
- head = Regexp.last_match(1)
131
- "<head>#{head}<style>#{CSSminify.compress(css)}</style></head>"
132
- end
133
-
134
- # If no <head> tag is found, insert the CSS at the start of the output
135
- if !page.output.match(%r{<head>(.*?)</head>}m)
136
- Jekyll.logger.debug 'GFMA:', "No <head> tag found in '#{page.path}', inserting CSS at the beginning of the page."
137
- page.output = "<head><style>#{CSSminify.compress(css)}</style></head>" + page.output
138
- end
139
- end
140
- end
141
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'octicons'
4
+ require 'cssminify'
5
+ require 'liquid/template'
6
+
7
+ ADMONITION_ICONS = {
8
+ 'important' => 'report',
9
+ 'note' => 'info',
10
+ 'tip' => 'light-bulb',
11
+ 'warning' => 'alert',
12
+ 'caution' => 'stop'
13
+ }.freeze
14
+
15
+ # JekyllGFMAdmonitions is a module that provides functionality to process and
16
+ # convert GitHub-flavored markdown admonitions into HTML within Jekyll.
17
+ module JekyllGFMAdmonitions
18
+ # GFMAdmonitionConverter is a Jekyll generator that converts custom
19
+ # admonition blocks in markdown (e.g., `> [!IMPORTANT]`) into styled HTML
20
+ # alert boxes with icons.
21
+ #
22
+ # This generator processes both posts and pages, replacing admonition
23
+ # syntax with HTML markup that includes appropriate iconography and CSS styling.
24
+ class GFMAdmonitionConverter < Jekyll::Generator
25
+ safe true
26
+ priority :lowest
27
+ @admonition_pages = []
28
+
29
+ class << self
30
+ attr_reader :admonition_pages
31
+ end
32
+
33
+
34
+ def generate(site)
35
+ init_converter(site)
36
+ process_collections(site)
37
+ process_pages(site)
38
+ Jekyll.logger.info 'GFMA:', 'Converted admonitions in' \
39
+ " #{self.class.admonition_pages.length} file(s)."
40
+ end
41
+
42
+ def init_converter(site)
43
+ @markdown = site.converters.find { |c| c.is_a?(Jekyll::Converters::Markdown) }
44
+ return if @markdown
45
+
46
+ raise 'Markdown converter not found. Please ensure that you have a markdown' \
47
+ ' converter configured in your Jekyll site.'
48
+ end
49
+
50
+ def process_collections(site)
51
+ site.collections.each do |name, collection|
52
+ collection.docs.each do |doc|
53
+ Jekyll.logger.debug 'GFMA:', "Processing collection '#{name}' document '#{doc.path}' (#{doc.content.length} characters)."
54
+ process_doc_content(doc)
55
+ end
56
+ end
57
+ end
58
+
59
+ def process_pages(site)
60
+ site.pages.each do |page|
61
+ Jekyll.logger.debug 'GFMA:', "Processing page '#{page.path}' (#{page.content.length} characters)."
62
+ process_doc_content(page)
63
+ end
64
+ end
65
+
66
+ def process_doc_content(doc)
67
+ original_content = doc.content.dup
68
+ process_doc(doc)
69
+
70
+ return unless doc.content != original_content
71
+
72
+ # Store a reference to all the pages we modified, to inject the CSS post render
73
+ # (otherwise GitHub Pages sanitizes the CSS into plaintext)
74
+ self.class.admonition_pages << doc
75
+ end
76
+
77
+ def process_doc(doc)
78
+ # Return early if content is empty
79
+ return if doc.content.empty?
80
+
81
+ # If the content is frozen, we need to duplicate it so that we can modify it
82
+ doc.content = doc.content.dup unless doc.content.frozen?
83
+
84
+ code_blocks = []
85
+ # Temporarily replace code blocks by a tag, so that we don't process any admonitions
86
+ # inside of code blocks.
87
+ doc.content.gsub!(/(?:^|\n)(?<!>)\s*```.*?```/m) do |match|
88
+ code_blocks << match
89
+ "```{{CODE_BLOCK_#{code_blocks.length - 1}}}```"
90
+ end
91
+
92
+ convert_admonitions(doc)
93
+
94
+ # Put the code blocks back in place
95
+ doc.content.gsub!(/```\{\{CODE_BLOCK_(\d+)}}```/) do
96
+ code_blocks[::Regexp.last_match(1).to_i]
97
+ end
98
+ end
99
+
100
+ def convert_admonitions(doc)
101
+ doc.content.gsub!(/^(\s*)>\s*\[!(IMPORTANT|NOTE|WARNING|TIP|CAUTION)\]([^\n]*)\n((?:\1\s*>\s*[^\n]*(?:\n|$))(?:(?!\s*>\s*\[!)\1\s*>\s*[^\n]*(?:\n|$))*)/) do
102
+ initial_indent = ::Regexp.last_match(1)
103
+ type = ::Regexp.last_match(2).downcase
104
+ title = ::Regexp.last_match(3).strip.empty? ? type.capitalize : ::Regexp.last_match(3).strip
105
+ text = ::Regexp.last_match(4).gsub(/^#{Regexp.escape(initial_indent)}\s*>\s*/, '').strip
106
+
107
+ icon = Octicons::Octicon.new(ADMONITION_ICONS[type]).to_svg
108
+ admonition_html(type, title, text, icon)
109
+ end
110
+
111
+ # 🛠 Ensure a blank line exists after each admonition block to prevent Markdown parsing issues.
112
+ doc.content.gsub!(/(<\/div>)(?!\n\n)/, "\\1\n\n")
113
+ end
114
+
115
+ def admonition_html(type, title, text, icon)
116
+ "<div class='markdown-alert markdown-alert-#{type}'>" \
117
+ "<p class='markdown-alert-title'>#{icon} #{title}</p>" \
118
+ "#{@markdown.convert(text)}" \
119
+ "</div>"
120
+ end
121
+ end
122
+
123
+ # Insert the minified CSS before the closing head tag of all pages we put admonitions on
124
+ Jekyll::Hooks.register :site, :post_render do
125
+ Jekyll.logger.info 'GFMA:', "Inserting admonition CSS in #{GFMAdmonitionConverter.admonition_pages.length} page(s)."
126
+
127
+ GFMAdmonitionConverter.admonition_pages.each do |page|
128
+ Jekyll.logger.debug 'GFMA:', "Appending admonition style to '#{page.path}'."
129
+ css = File.read(File.expand_path('../assets/admonitions.css', __dir__))
130
+
131
+ page.output.gsub!(%r{<head>(.*?)</head>}m) do |match|
132
+ head = Regexp.last_match(1)
133
+ "<head>#{head}<style>#{CSSminify.compress(css)}</style></head>"
134
+ end
135
+
136
+ # If no <head> tag is found, insert the CSS at the start of the output
137
+ if !page.output.match(%r{<head>(.*?)</head>}m)
138
+ Jekyll.logger.debug 'GFMA:', "No <head> tag found in '#{page.path}', inserting CSS at the beginning of the page."
139
+ page.output = "<head><style>#{CSSminify.compress(css)}</style></head>" + page.output
140
+ end
141
+ end
142
+ end
143
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-gfm-admonitions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robin De Schepper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-06 00:00:00.000000000 Z
11
+ date: 2025-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cssminify