jekyll-webawesome 0.1.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 +7 -0
- data/CHANGELOG.md +17 -0
- data/LICENSE.txt +9 -0
- data/README.md +397 -0
- data/jekyll-webawesome.gemspec +42 -0
- data/lib/jekyll/webawesome/code_block_transformer.rb +110 -0
- data/lib/jekyll/webawesome/plugin.rb +40 -0
- data/lib/jekyll/webawesome/transformer.rb +23 -0
- data/lib/jekyll/webawesome/transformers/badge_transformer.rb +48 -0
- data/lib/jekyll/webawesome/transformers/base_transformer.rb +65 -0
- data/lib/jekyll/webawesome/transformers/button_transformer.rb +68 -0
- data/lib/jekyll/webawesome/transformers/callout_transformer.rb +72 -0
- data/lib/jekyll/webawesome/transformers/card_transformer.rb +121 -0
- data/lib/jekyll/webawesome/transformers/details_transformer.rb +54 -0
- data/lib/jekyll/webawesome/transformers/icon_transformer.rb +82 -0
- data/lib/jekyll/webawesome/transformers/tabs_transformer.rb +53 -0
- data/lib/jekyll/webawesome/transformers/tag_transformer.rb +44 -0
- data/lib/jekyll/webawesome/transformers.rb +14 -0
- data/lib/jekyll/webawesome/version.rb +7 -0
- data/lib/jekyll/webawesome.rb +47 -0
- data/lib/jekyll-webawesome.rb +3 -0
- data/lib/jekyll_webawesome.rb +3 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 11da0d2da16359893d07591941d1dcca5184c7befcaa03c95adab45b4945e2c2
|
4
|
+
data.tar.gz: e573335ac4e9caa1c46585593f1ab0718c58e58e03060dcb21a159a16324678a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d90cc934527c25df1c8444cb1e193f383ae60f6a4a679c590cffa1fdf25606d10f728b5bd30ab41cb96c44d1053300d49c8fdb4943b5568ff47c20d2f23636eb
|
7
|
+
data.tar.gz: 364c6eb910786df9e07ee90629c2a2af9fe8062d97e7837596f5ae320318eb2e65f25364c468995f79b70cbd65fd49a36628ee64aa009588349abd6ee0b39b9f
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [0.1.0] - 2025-08-09
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Initial release of jekyll-webawesome gem
|
14
|
+
- Support for callout components (:::info, :::success, :::warning, :::danger, :::neutral)
|
15
|
+
- Support for details/summary components (^^^...>>>...^^^)
|
16
|
+
- Support for tab group components (++++++...++++++)
|
17
|
+
- Automatic Jekyll hooks integration
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Janne Warén
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,397 @@
|
|
1
|
+
# jekyll-webawesome
|
2
|
+
|
3
|
+
This is a plugin for [Jekyll](https://jekyllrb.com/) that transforms custom Markdown syntax into [Web Awesome](https://webawesome.com/) components. Use a simple, intuitive Markdown-like syntax to create rich interactive components in your Jekyll website. The goal is to keep HTML out of Markdown files and create an easier experience for non-developers to update content.
|
4
|
+
|
5
|
+
The context here is a technical documentation website, and being limited to just basic Markdown features often results in a boring wall of text which the user won't read. The aim is to help create a more visually interesting page to read, by mixing in some components like callouts, tabs, cards and collapsible summary/details.
|
6
|
+
|
7
|
+
## Web Awesome components
|
8
|
+
|
9
|
+
This plugin focuses on the most commonly used Web Awesome components for Jekyll content. Components are organized by support status:
|
10
|
+
|
11
|
+
### Currently supported
|
12
|
+
|
13
|
+
| Component | Primary Syntax | Alternative Syntax | HTML Output |
|
14
|
+
|-----------|----------------|-------------------|-------------|
|
15
|
+
| **Badge** | `!!!variant` | `:::wa-badge variant` | `<wa-badge variant="brand">content</wa-badge>` |
|
16
|
+
| **Button** | `%%%variant` | `:::wa-button variant` | `<wa-button variant="brand" href="url">text</wa-button>` or `<wa-button variant="brand">text</wa-button>` |
|
17
|
+
| **Callouts** | `:::info` | `:::wa-callout info` | `<wa-callout variant="brand"><wa-icon name="circle-info"></wa-icon>content</wa-callout>` |
|
18
|
+
| **Card** | `===` | `:::wa-card` | `<wa-card>content</wa-card>` |
|
19
|
+
| **Details** | `^^^` | `:::wa-details` | `<wa-details><summary>summary</summary>content</wa-details>` |
|
20
|
+
| **Tab Group** | `++++++` | `:::wa-tabs` | `<wa-tab-group><wa-tab>content</wa-tab></wa-tab-group>` |
|
21
|
+
| **Tag** | `@@@brand` | `:::wa-tag brand` | `<wa-tag variant="brand">content</wa-tag>` |
|
22
|
+
|
23
|
+
### Planned
|
24
|
+
|
25
|
+
These content-focused components will get dedicated syntax in future releases:
|
26
|
+
|
27
|
+
| Component | Primary Syntax | Alternative syntax | HTML Output |
|
28
|
+
|-----------|----------------------|-------------------|-------------|
|
29
|
+
| **Copy Button** | `<<<` | `:::wa-copy-button` | `<wa-copy-button>content</wa-copy-button>` |
|
30
|
+
| **Divider** | `\|\|\|` | `:::wa-divider` | `<wa-divider></wa-divider>` |
|
31
|
+
| **Icon** | `$$$icon-name` | `:::wa-icon name` | `<wa-icon name="icon-name"></wa-icon>` |
|
32
|
+
| **Progress Bar** | `&&&value` | `:::wa-progress-bar value` | `<wa-progress-bar value="50"></wa-progress-bar>` |
|
33
|
+
| **Rating** | `???value` | `:::wa-rating value` | `<wa-rating value="4"></wa-rating>` |
|
34
|
+
| **Avatar** | (none) | `:::wa-avatar` | `<wa-avatar>` |
|
35
|
+
| **QR Code** | (none) | `:::wa-qr-code` | `<wa-qr-code>` |
|
36
|
+
| **Skeleton** | (none) | `:::wa-skeleton` | `<wa-skeleton>` |
|
37
|
+
| **Spinner** | (none) | `:::wa-spinner` | `<wa-spinner>` |
|
38
|
+
| **Tooltip** | (none) | `:::wa-tooltip` | `<wa-tooltip>` |
|
39
|
+
|
40
|
+
Not all components will make sense to include here, to be included in the "prose" content of a web page. Some components are more suitable to be used in layouts or used in the page as includes, too complicated for this purpose.
|
41
|
+
|
42
|
+
Both syntax styles work identically and can be mixed within the same document.
|
43
|
+
|
44
|
+
## Installation
|
45
|
+
|
46
|
+
Add this line to your application's Gemfile:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
gem 'jekyll-webawesome'
|
50
|
+
```
|
51
|
+
|
52
|
+
Add the plugin to your Jekyll site's `_config.yml`:
|
53
|
+
|
54
|
+
```yaml
|
55
|
+
plugins:
|
56
|
+
- jekyll-webawesome
|
57
|
+
```
|
58
|
+
|
59
|
+
And add configuration options as needed in `_config.yml`:
|
60
|
+
|
61
|
+
```yaml
|
62
|
+
webawesome:
|
63
|
+
# Enable debug output to see which files are being processed
|
64
|
+
debug: true
|
65
|
+
```
|
66
|
+
|
67
|
+
And then execute:
|
68
|
+
|
69
|
+
```bash
|
70
|
+
bundle install
|
71
|
+
```
|
72
|
+
|
73
|
+
## Live Examples
|
74
|
+
|
75
|
+
See the plugin in action with a complete Jekyll site showcasing all supported components:
|
76
|
+
|
77
|
+
```bash
|
78
|
+
cd examples
|
79
|
+
bundle install
|
80
|
+
bundle exec jekyll serve
|
81
|
+
```
|
82
|
+
|
83
|
+
Then visit `http://localhost:4000` to see all components rendered with Web Awesome styling.
|
84
|
+
|
85
|
+
> **Note**: All components support dual syntax. You can use either the primary syntax (shown in examples below) or the alternative `:::wa-component` syntax.
|
86
|
+
|
87
|
+
## Components
|
88
|
+
|
89
|
+
### Callouts
|
90
|
+
|
91
|
+
Create callouts using the `:::` syntax:
|
92
|
+
|
93
|
+
```markdown
|
94
|
+
:::info
|
95
|
+
This is an info callout with **bold text** and [links](https://example.com).
|
96
|
+
:::
|
97
|
+
|
98
|
+
:::success
|
99
|
+
This is a success callout.
|
100
|
+
:::
|
101
|
+
|
102
|
+
:::warning
|
103
|
+
This is a warning callout.
|
104
|
+
:::
|
105
|
+
|
106
|
+
:::danger
|
107
|
+
This is a danger callout.
|
108
|
+
:::
|
109
|
+
|
110
|
+
:::neutral
|
111
|
+
This is a neutral callout.
|
112
|
+
:::
|
113
|
+
```
|
114
|
+
|
115
|
+
These transform into Web Awesome callout components with appropriate icons and styling.
|
116
|
+
|
117
|
+
### Cards
|
118
|
+
|
119
|
+
Create cards using the `===` syntax:
|
120
|
+
|
121
|
+
```markdown
|
122
|
+
===
|
123
|
+
This is a basic card with just content.
|
124
|
+
===
|
125
|
+
```
|
126
|
+
|
127
|
+
#### Cards with Headers
|
128
|
+
|
129
|
+
The first heading (`#`) automatically becomes the card header:
|
130
|
+
|
131
|
+
```markdown
|
132
|
+
===
|
133
|
+
# Card Title
|
134
|
+
This is the card content that appears in the main area.
|
135
|
+
===
|
136
|
+
```
|
137
|
+
|
138
|
+
#### Cards with Media
|
139
|
+
|
140
|
+
The first image automatically becomes the card media:
|
141
|
+
|
142
|
+
```markdown
|
143
|
+
===
|
144
|
+

|
145
|
+
# Featured Content
|
146
|
+
This card includes both an image and a title.
|
147
|
+
===
|
148
|
+
```
|
149
|
+
|
150
|
+
#### Cards with Footers
|
151
|
+
|
152
|
+
Links at the end of the card content automatically become footer buttons:
|
153
|
+
|
154
|
+
```markdown
|
155
|
+
===
|
156
|
+
# Get Started
|
157
|
+
Ready to begin your journey?
|
158
|
+
[Learn More](https://example.com)
|
159
|
+
===
|
160
|
+
```
|
161
|
+
|
162
|
+
#### Complete Cards
|
163
|
+
|
164
|
+
You can combine all elements for rich content cards:
|
165
|
+
|
166
|
+
```markdown
|
167
|
+
===filled
|
168
|
+

|
169
|
+
# Complete Example
|
170
|
+
This card has media, header, content, and footer with a filled appearance.
|
171
|
+
[Get Started](https://example.com)
|
172
|
+
===
|
173
|
+
```
|
174
|
+
|
175
|
+
#### Card Appearances
|
176
|
+
|
177
|
+
You can specify different visual styles:
|
178
|
+
|
179
|
+
```markdown
|
180
|
+
===filled
|
181
|
+
# Filled Card
|
182
|
+
This card uses the filled appearance.
|
183
|
+
===
|
184
|
+
|
185
|
+
===plain
|
186
|
+
# Plain Card
|
187
|
+
This card uses the plain appearance.
|
188
|
+
===
|
189
|
+
|
190
|
+
===filled-outlined
|
191
|
+
# Filled Outlined Card
|
192
|
+
This card uses the filled-outlined appearance.
|
193
|
+
===
|
194
|
+
|
195
|
+
===accent
|
196
|
+
# Accent Card
|
197
|
+
This card uses the accent appearance for emphasis.
|
198
|
+
===
|
199
|
+
```
|
200
|
+
|
201
|
+
### Tags
|
202
|
+
|
203
|
+
Create tags using the `@@@` syntax:
|
204
|
+
|
205
|
+
```markdown
|
206
|
+
@@@
|
207
|
+
Basic tag
|
208
|
+
@@@
|
209
|
+
|
210
|
+
@@@brand
|
211
|
+
Version 2.0
|
212
|
+
@@@
|
213
|
+
|
214
|
+
@@@success
|
215
|
+
Completed
|
216
|
+
@@@
|
217
|
+
|
218
|
+
@@@warning
|
219
|
+
In Progress
|
220
|
+
@@@
|
221
|
+
|
222
|
+
@@@danger
|
223
|
+
Critical Issue
|
224
|
+
@@@
|
225
|
+
|
226
|
+
@@@neutral
|
227
|
+
Documentation
|
228
|
+
@@@
|
229
|
+
```
|
230
|
+
|
231
|
+
These transform into Web Awesome tag components with appropriate colors and styling. Tags support markdown formatting within the content:
|
232
|
+
|
233
|
+
```markdown
|
234
|
+
@@@brand
|
235
|
+
**v3.0** Beta
|
236
|
+
@@@
|
237
|
+
|
238
|
+
@@@success
|
239
|
+
[View Results](https://example.com)
|
240
|
+
@@@
|
241
|
+
```
|
242
|
+
|
243
|
+
### Details/Summary (Collapsible Content)
|
244
|
+
|
245
|
+
Create collapsible content using the `^^^` syntax:
|
246
|
+
|
247
|
+
```markdown
|
248
|
+
^^^
|
249
|
+
Click to expand this summary
|
250
|
+
>>>
|
251
|
+
This is the detailed content that can be collapsed and expanded.
|
252
|
+
|
253
|
+
You can include:
|
254
|
+
- Lists
|
255
|
+
- **Bold text**
|
256
|
+
- [Links](https://example.com)
|
257
|
+
- Code blocks
|
258
|
+
^^^
|
259
|
+
```
|
260
|
+
|
261
|
+
You can also specify appearance styles:
|
262
|
+
|
263
|
+
```markdown
|
264
|
+
^^^filled
|
265
|
+
Filled appearance summary
|
266
|
+
>>>
|
267
|
+
Content goes here
|
268
|
+
^^^
|
269
|
+
|
270
|
+
^^^plain
|
271
|
+
Plain appearance summary
|
272
|
+
>>>
|
273
|
+
Content goes here
|
274
|
+
^^^
|
275
|
+
|
276
|
+
^^^filled-outlined
|
277
|
+
Filled and outlined appearance summary
|
278
|
+
>>>
|
279
|
+
Content goes here
|
280
|
+
^^^
|
281
|
+
```
|
282
|
+
|
283
|
+
### Tab Groups
|
284
|
+
|
285
|
+
Create tabbed content using the `++++++` syntax:
|
286
|
+
|
287
|
+
```markdown
|
288
|
+
++++++
|
289
|
+
+++ First Tab
|
290
|
+
Content for the first tab goes here.
|
291
|
+
+++
|
292
|
+
|
293
|
+
+++ Second Tab
|
294
|
+
Content for the second tab.
|
295
|
+
+++
|
296
|
+
|
297
|
+
+++ Third Tab
|
298
|
+
Content for the third tab.
|
299
|
+
+++
|
300
|
+
++++++
|
301
|
+
```
|
302
|
+
|
303
|
+
You can specify tab placement:
|
304
|
+
|
305
|
+
```markdown
|
306
|
+
++++++start
|
307
|
+
+++ Tab 1
|
308
|
+
Content here
|
309
|
+
+++
|
310
|
+
+++ Tab 2
|
311
|
+
More content
|
312
|
+
+++
|
313
|
+
++++++
|
314
|
+
|
315
|
+
++++++bottom
|
316
|
+
+++ Tab 1
|
317
|
+
Content here
|
318
|
+
+++
|
319
|
+
+++ Tab 2
|
320
|
+
More content
|
321
|
+
+++
|
322
|
+
++++++
|
323
|
+
```
|
324
|
+
|
325
|
+
Supported placements: `top` (default), `bottom`, `start`, `end`.
|
326
|
+
|
327
|
+
## Component Reference
|
328
|
+
|
329
|
+
### Callout Types
|
330
|
+
|
331
|
+
| Type | Icon | Variant |
|
332
|
+
|------|------|---------|
|
333
|
+
| `info` | circle-info | brand |
|
334
|
+
| `success` | circle-check | success |
|
335
|
+
| `warning` | triangle-exclamation | warning |
|
336
|
+
| `danger` | circle-exclamation | danger |
|
337
|
+
| `neutral` | gear | neutral |
|
338
|
+
|
339
|
+
### Card Options
|
340
|
+
|
341
|
+
| Type | Description |
|
342
|
+
|------|-------------|
|
343
|
+
| `outlined` (default) | Default outlined appearance |
|
344
|
+
| `filled` | Filled background appearance |
|
345
|
+
| `plain` | Minimal plain appearance |
|
346
|
+
| `filled-outlined` | Combination of filled and outlined |
|
347
|
+
| `accent` | Accent appearance for emphasis |
|
348
|
+
|
349
|
+
### Card Structure
|
350
|
+
|
351
|
+
Cards automatically parse content into these slots:
|
352
|
+
|
353
|
+
- **Media**: First image becomes media slot
|
354
|
+
- **Header**: First `#` heading becomes header slot
|
355
|
+
- **Content**: Remaining content becomes main content
|
356
|
+
- **Footer**: Trailing links become footer buttons
|
357
|
+
|
358
|
+
### Tag Variants
|
359
|
+
|
360
|
+
| Type | Description |
|
361
|
+
|------|-------------|
|
362
|
+
| (none) | Default neutral appearance |
|
363
|
+
| `brand` | Primary brand color |
|
364
|
+
| `success` | Success/positive state |
|
365
|
+
| `warning` | Warning/caution state |
|
366
|
+
| `danger` | Error/critical state |
|
367
|
+
| `neutral` | Neutral/informational state |
|
368
|
+
|
369
|
+
### Details Appearances
|
370
|
+
|
371
|
+
| Type | CSS Class |
|
372
|
+
|------|-----------|
|
373
|
+
| `outlined` (default) | outlined |
|
374
|
+
| `filled` | filled |
|
375
|
+
| `plain` | plain |
|
376
|
+
| `filled-outlined` | filled outlined |
|
377
|
+
|
378
|
+
### Tab Placements
|
379
|
+
|
380
|
+
- `top` (default)
|
381
|
+
- `bottom`
|
382
|
+
- `start`
|
383
|
+
- `end`
|
384
|
+
|
385
|
+
## Requirements
|
386
|
+
|
387
|
+
- Jekyll >= 3.7
|
388
|
+
- Kramdown >= 2.0
|
389
|
+
- Web Awesome CSS/JS loaded in your site
|
390
|
+
|
391
|
+
## Contributing
|
392
|
+
|
393
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/jannewaren/jekyll-webawesome](https://github.com/jannewaren/jekyll-webawesome).
|
394
|
+
|
395
|
+
## License
|
396
|
+
|
397
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/jekyll/webawesome/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'jekyll-webawesome'
|
7
|
+
spec.version = Jekyll::WebAwesome::VERSION
|
8
|
+
spec.authors = ['Janne Waren']
|
9
|
+
spec.email = ['janne.waren@iki.fi']
|
10
|
+
|
11
|
+
spec.summary = 'Jekyll plugin for Web Awesome components'
|
12
|
+
spec.description = 'A Jekyll plugin that transforms custom Markdown syntax into Web Awesome components.'
|
13
|
+
spec.homepage = 'https://github.com/jannewaren/jekyll-webawesome'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = '>= 3.2'
|
16
|
+
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['source_code_uri'] = "#{spec.homepage}/tree/main"
|
19
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
24
|
+
Dir.glob('lib/**/*.rb') + %w[
|
25
|
+
README.md
|
26
|
+
CHANGELOG.md
|
27
|
+
LICENSE.txt
|
28
|
+
jekyll-webawesome.gemspec
|
29
|
+
]
|
30
|
+
end
|
31
|
+
spec.bindir = 'exe'
|
32
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ['lib']
|
34
|
+
|
35
|
+
spec.add_dependency 'jekyll', '>= 3.7', '< 5.0'
|
36
|
+
spec.add_dependency 'kramdown', '~> 2.0'
|
37
|
+
|
38
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
39
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
40
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
41
|
+
spec.add_development_dependency 'rubocop', '~> 1.0'
|
42
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module WebAwesome
|
5
|
+
# Transforms markdown code blocks to Jekyll highlight syntax
|
6
|
+
module CodeBlockTransformer
|
7
|
+
CODE_BLOCK_PATTERN = /```([a-zA-Z0-9.+#_-]+)?(\n.*?)```/m
|
8
|
+
|
9
|
+
# Class variable to store protected blocks across hook calls
|
10
|
+
@@protected_blocks = {}
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def clear_protected_blocks
|
14
|
+
@@protected_blocks.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
# Check if a code block contains WebAwesome syntax that should be preserved
|
18
|
+
def contains_webawesome_syntax?(content)
|
19
|
+
# Check for WebAwesome patterns
|
20
|
+
callout_pattern = /^:::(info|success|neutral|warning|danger)/m
|
21
|
+
details_pattern = /^\^\^\^/m
|
22
|
+
tabs_pattern = /^\+{6}/m
|
23
|
+
|
24
|
+
content.match?(callout_pattern) || content.match?(details_pattern) || content.match?(tabs_pattern)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Transform code blocks from markdown syntax to Jekyll highlight tags
|
28
|
+
def transform_code_blocks(content)
|
29
|
+
counter = @@protected_blocks.size
|
30
|
+
|
31
|
+
# First pass: protect markdown code blocks that contain WebAwesome syntax
|
32
|
+
content = content.gsub(CODE_BLOCK_PATTERN) do |match|
|
33
|
+
language = Regexp.last_match(1)
|
34
|
+
code_content = Regexp.last_match(2).strip
|
35
|
+
|
36
|
+
# If this is a markdown code block containing WebAwesome syntax, protect it
|
37
|
+
if language && language.downcase == 'markdown' && contains_webawesome_syntax?(code_content)
|
38
|
+
placeholder = "<!--PROTECTED_WEBAWESOME_EXAMPLE_#{counter}-->"
|
39
|
+
@@protected_blocks[placeholder] = match
|
40
|
+
counter += 1
|
41
|
+
placeholder
|
42
|
+
else
|
43
|
+
match # Leave other code blocks for normal processing
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Second pass: transform remaining code blocks normally
|
48
|
+
content.gsub(CODE_BLOCK_PATTERN) do |match|
|
49
|
+
language = Regexp.last_match(1)
|
50
|
+
code_content = Regexp.last_match(2).strip
|
51
|
+
|
52
|
+
if language && language.downcase != 'plain'
|
53
|
+
transformed = "{% highlight #{language} %}\n#{code_content}\n{% endhighlight %}"
|
54
|
+
transformed
|
55
|
+
else
|
56
|
+
match # Return original block if no language or 'plain'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Restore protected WebAwesome example blocks after WaElementTransformer processing
|
62
|
+
def restore_protected_blocks(content)
|
63
|
+
@@protected_blocks.each do |placeholder, original_block|
|
64
|
+
content = content.gsub(placeholder, original_block)
|
65
|
+
end
|
66
|
+
content
|
67
|
+
end
|
68
|
+
|
69
|
+
def process(content)
|
70
|
+
transform_code_blocks(content)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Register hooks directly in the transformer module
|
75
|
+
# Clear protected blocks at start of build
|
76
|
+
Jekyll::Hooks.register :site, :pre_render do |_site|
|
77
|
+
CodeBlockTransformer.clear_protected_blocks
|
78
|
+
end
|
79
|
+
|
80
|
+
Jekyll::Hooks.register :documents, :pre_render, priority: 30 do |document|
|
81
|
+
next unless document.relative_path =~ /.*\.md$/i
|
82
|
+
|
83
|
+
puts "Jekyll::WebAwesome::CodeBlockTransformer processing document: #{document.relative_path}\n"
|
84
|
+
document.content = CodeBlockTransformer.transform_code_blocks(document.content)
|
85
|
+
end
|
86
|
+
|
87
|
+
Jekyll::Hooks.register :pages, :pre_render, priority: 30 do |page|
|
88
|
+
next unless page.relative_path =~ /.*\.md$/i
|
89
|
+
|
90
|
+
puts "Jekyll::WebAwesome::CodeBlockTransformer processing page: #{page.relative_path}\n"
|
91
|
+
page.content = CodeBlockTransformer.transform_code_blocks(page.content)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Register hooks to restore protected blocks after WaElementTransformer
|
95
|
+
Jekyll::Hooks.register :documents, :pre_render, priority: 10 do |document|
|
96
|
+
next unless document.relative_path =~ /.*\.md$/i
|
97
|
+
|
98
|
+
puts "Jekyll::WebAwesome::CodeBlockTransformer restoring code blocks in document: #{document.relative_path}\n"
|
99
|
+
document.content = CodeBlockTransformer.restore_protected_blocks(document.content)
|
100
|
+
end
|
101
|
+
|
102
|
+
Jekyll::Hooks.register :pages, :pre_render, priority: 10 do |page|
|
103
|
+
next unless page.relative_path =~ /.*\.md$/i
|
104
|
+
|
105
|
+
puts "Jekyll::WebAwesome::CodeBlockTransformer restoring code blocks in page: #{page.relative_path}\n"
|
106
|
+
page.content = CodeBlockTransformer.restore_protected_blocks(page.content)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'transformer'
|
4
|
+
require_relative 'code_block_transformer'
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module WebAwesome
|
8
|
+
# Plugin class that registers hooks for pre-render processing
|
9
|
+
class Plugin
|
10
|
+
# Check if debug mode is enabled from various configuration sources
|
11
|
+
def self.debug_enabled?(site)
|
12
|
+
return true if Jekyll::WebAwesome.configuration&.debug_mode
|
13
|
+
return true if site.config.dig('webawesome', 'debug')
|
14
|
+
return true if site.config['webawesome_debug']
|
15
|
+
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if a file is a markdown file
|
20
|
+
def self.markdown_file?(filepath)
|
21
|
+
filepath.to_s.match?(/\.md$/i)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Register hooks for pre-render processing (before markdown conversion)
|
25
|
+
Jekyll::Hooks.register :documents, :pre_render do |document|
|
26
|
+
next unless markdown_file?(document.relative_path)
|
27
|
+
|
28
|
+
puts "Jekyll::WebAwesome Processing document (pre-render): #{document.relative_path}\n" if debug_enabled?(document.site)
|
29
|
+
document.content = Transformer.process(document.content)
|
30
|
+
end
|
31
|
+
|
32
|
+
Jekyll::Hooks.register :pages, :pre_render do |page|
|
33
|
+
next unless markdown_file?(page.relative_path)
|
34
|
+
|
35
|
+
puts "Jekyll::WebAwesome Processing page (pre-render): #{page.relative_path}\n" if debug_enabled?(page.site)
|
36
|
+
page.content = Transformer.process(page.content)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jekyll'
|
4
|
+
require 'kramdown'
|
5
|
+
require_relative 'transformers'
|
6
|
+
|
7
|
+
module Jekyll
|
8
|
+
module WebAwesome
|
9
|
+
# Main transformer that orchestrates all component transformers
|
10
|
+
class Transformer
|
11
|
+
def self.process(content)
|
12
|
+
content = BadgeTransformer.transform(content)
|
13
|
+
content = ButtonTransformer.transform(content)
|
14
|
+
content = CalloutTransformer.transform(content)
|
15
|
+
content = CardTransformer.transform(content)
|
16
|
+
content = DetailsTransformer.transform(content)
|
17
|
+
content = IconTransformer.transform(content)
|
18
|
+
content = TagTransformer.transform(content)
|
19
|
+
TabsTransformer.transform(content)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_transformer'
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
module WebAwesome
|
7
|
+
# Transforms badge syntax into wa-badge elements
|
8
|
+
# Primary syntax: !!!variant?\ncontent\n!!!
|
9
|
+
# Alternative syntax: :::wa-badge variant?\ncontent\n:::
|
10
|
+
# Variants: brand, success, neutral, warning, danger
|
11
|
+
class BadgeTransformer < BaseTransformer
|
12
|
+
def self.transform(content)
|
13
|
+
# Define both regex patterns
|
14
|
+
primary_regex = /^!!!(brand|success|neutral|warning|danger)?\n(.*?)\n!!!/m
|
15
|
+
alternative_regex = /^:::wa-badge\s*(brand|success|neutral|warning|danger)?\n(.*?)\n:::/m
|
16
|
+
|
17
|
+
# Define shared transformation logic
|
18
|
+
transform_proc = proc do |variant, badge_content|
|
19
|
+
badge_content = badge_content.strip
|
20
|
+
|
21
|
+
build_badge_html(badge_content, variant)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Apply both patterns
|
25
|
+
patterns = dual_syntax_patterns(primary_regex, alternative_regex, transform_proc)
|
26
|
+
apply_multiple_patterns(content, patterns)
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
private
|
31
|
+
|
32
|
+
def build_badge_html(content, variant)
|
33
|
+
variant_attr = variant ? " variant=\"#{variant}\"" : ''
|
34
|
+
badge_html = markdown_to_html(content).strip
|
35
|
+
|
36
|
+
# Remove paragraph tags if the content is just text
|
37
|
+
badge_html = badge_html.gsub(%r{^<p>(.*)</p>$}m, '\1')
|
38
|
+
|
39
|
+
# Fix whitespace issues in Web Awesome badges by ensuring proper spacing
|
40
|
+
# Replace spaces after closing tags with non-breaking spaces to prevent CSS collapse
|
41
|
+
badge_html = badge_html.gsub(%r{(</\w+>)\s+}, '\1 ')
|
42
|
+
|
43
|
+
"<wa-badge#{variant_attr}>#{badge_html}</wa-badge>"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|