jekyll-github-card 0.1.0 → 0.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 +4 -4
- data/CHANGELOG.md +34 -0
- data/LICENSE +2 -1
- data/README.md +182 -25
- data/Rakefile +14 -0
- data/assets/css/github-card.css +146 -84
- data/lib/jekyll-github-card/generator.rb +44 -0
- data/lib/jekyll-github-card/tag.rb +187 -0
- data/lib/jekyll-github-card/version.rb +3 -2
- data/lib/jekyll-github-card.rb +12 -0
- metadata +58 -10
- data/assets/js/github-card.js +0 -104
- data/lib/jekyll-github-card/jekyll-github-card.rb +0 -89
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e9b401cafbd8f56e70fde46581e04862f7b5db93b9145923600cbe9606e5c80
|
|
4
|
+
data.tar.gz: '092cf4dbc24ca5b4b4a1b06e5fa1c17cc1f16f2f3194b851d02984d44bd66f8f'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f046ee51c03c30ee68aec16426119fbadf42c045500094199e7c871d049dd309422722b5f194274f35cd53297550db7510df60b12def2ed239986b2888424bf0
|
|
7
|
+
data.tar.gz: 7e5a81ec424d3bea58932054e7a21c8c0ffec7b36772b0db52a5c3be22b383c2043c5df8f4e2ee2d93feb9aa3334ce37fecd7200153fb2d22196ec8827d4647b
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
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.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2025-12-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `{% github user/repo %}` Liquid tag for embedding GitHub repository cards
|
|
13
|
+
- Light and dark theme support
|
|
14
|
+
- Automatic detection via `prefers-color-scheme`
|
|
15
|
+
- Support for Chirpy theme's `data-mode` attribute
|
|
16
|
+
- Support for `data-theme` and class-based theme switching
|
|
17
|
+
- Repository information display:
|
|
18
|
+
- Repository name with link
|
|
19
|
+
- Description
|
|
20
|
+
- Primary programming language with color indicator
|
|
21
|
+
- Star count (with K/M formatting)
|
|
22
|
+
- Fork count (with K/M formatting)
|
|
23
|
+
- Error handling for missing or inaccessible repositories
|
|
24
|
+
- In-memory caching for API responses
|
|
25
|
+
- Support for GitHub token authentication
|
|
26
|
+
- CSS custom properties for easy theming
|
|
27
|
+
- Responsive design
|
|
28
|
+
- XSS protection via HTML escaping
|
|
29
|
+
|
|
30
|
+
## [0.1.0] - 2025-12-11
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- Initial release
|
data/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2024 Your Name
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
|
22
|
+
|
data/README.md
CHANGED
|
@@ -1,61 +1,218 @@
|
|
|
1
1
|
# Jekyll GitHub Card
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://badge.fury.io/rb/jekyll-github-card)
|
|
4
|
+
[](https://github.com/r0x0d/jekyll-github-card/actions/workflows/test.yml)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
A Jekyll plugin that allows you to embed beautiful GitHub repository cards in your posts and pages using a simple Liquid tag. Supports both light and dark themes automatically.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
## Preview
|
|
9
|
+
|
|
10
|
+
### Dark Theme
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
### Light Theme
|
|
14
|
+

|
|
12
15
|
|
|
13
16
|
## Installation
|
|
14
17
|
|
|
15
18
|
Add this line to your Jekyll site's `Gemfile`:
|
|
16
19
|
|
|
17
20
|
```ruby
|
|
18
|
-
|
|
21
|
+
group :jekyll_plugins do
|
|
22
|
+
gem 'jekyll-github-card'
|
|
23
|
+
end
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then execute:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bundle install
|
|
19
30
|
```
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
Or install it yourself:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gem install jekyll-github-card
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Add to your Jekyll configuration
|
|
39
|
+
|
|
40
|
+
Add the plugin to your `_config.yml`:
|
|
22
41
|
|
|
23
42
|
```yaml
|
|
24
43
|
plugins:
|
|
25
44
|
- jekyll-github-card
|
|
26
45
|
```
|
|
27
46
|
|
|
28
|
-
|
|
47
|
+
### Include the CSS
|
|
48
|
+
|
|
49
|
+
Add the stylesheet to your layout (usually in `_includes/head.html` or your main layout file):
|
|
29
50
|
|
|
30
51
|
```html
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
<link rel="stylesheet" href="{{ '/assets/css/github-card.css' | relative_url }}">
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Or import it in your main SCSS file:
|
|
56
|
+
|
|
57
|
+
```scss
|
|
58
|
+
@import "github-card";
|
|
36
59
|
```
|
|
37
60
|
|
|
38
61
|
## Usage
|
|
39
62
|
|
|
40
|
-
|
|
63
|
+
Use the `{% github %}` tag in any post or page:
|
|
41
64
|
|
|
42
65
|
```liquid
|
|
43
66
|
{% github facebook/react %}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This will render a card showing:
|
|
70
|
+
- Repository name with link
|
|
71
|
+
- Description
|
|
72
|
+
- Primary programming language with color indicator
|
|
73
|
+
- Star count
|
|
74
|
+
- Fork count
|
|
75
|
+
|
|
76
|
+
### Examples
|
|
77
|
+
|
|
78
|
+
```liquid
|
|
79
|
+
{% github microsoft/vscode %}
|
|
80
|
+
{% github rails/rails %}
|
|
81
|
+
{% github jekyll/jekyll %}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Theme Support
|
|
85
|
+
|
|
86
|
+
The plugin automatically supports both light and dark themes through CSS.
|
|
87
|
+
|
|
88
|
+
### Automatic Detection
|
|
89
|
+
|
|
90
|
+
By default, the card respects the user's system preference via `prefers-color-scheme`.
|
|
91
|
+
|
|
92
|
+
### Manual Theme Control
|
|
93
|
+
|
|
94
|
+
#### For Chirpy Theme
|
|
95
|
+
|
|
96
|
+
Chirpy uses `data-mode="light"` on the HTML element for light mode. This is automatically supported:
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<html data-mode="light"> <!-- Light theme -->
|
|
100
|
+
<html> <!-- Dark theme (default) -->
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### For Other Themes
|
|
104
|
+
|
|
105
|
+
The CSS supports multiple theme conventions:
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<!-- Any of these will trigger light theme -->
|
|
109
|
+
<html data-mode="light">
|
|
110
|
+
<html data-theme="light">
|
|
111
|
+
<html class="light">
|
|
112
|
+
<div class="github-card light">
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Force a Specific Theme
|
|
44
116
|
|
|
45
|
-
|
|
117
|
+
Add the `light` or `dark` class directly to the card:
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<div class="github-card light">...</div>
|
|
121
|
+
<div class="github-card dark">...</div>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Configuration
|
|
125
|
+
|
|
126
|
+
### GitHub API Rate Limits
|
|
127
|
+
|
|
128
|
+
The plugin uses GitHub's public API, which has rate limits:
|
|
129
|
+
- **Unauthenticated**: 60 requests per hour
|
|
130
|
+
- **Authenticated**: 5,000 requests per hour
|
|
131
|
+
|
|
132
|
+
To increase the rate limit, set a GitHub token as an environment variable:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
export GITHUB_TOKEN=your_github_token
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For GitHub Actions or CI/CD:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
env:
|
|
142
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
46
143
|
```
|
|
47
144
|
|
|
48
|
-
|
|
145
|
+
### Caching
|
|
146
|
+
|
|
147
|
+
The plugin caches API responses in memory during the build process to minimize API calls.
|
|
148
|
+
|
|
149
|
+
## Customization
|
|
49
150
|
|
|
50
|
-
|
|
51
|
-
- Ruby 2.6+
|
|
52
|
-
- Works with Chirpy theme and most Jekyll themes
|
|
53
|
-
- Supports both light and dark modes
|
|
151
|
+
### CSS Variables
|
|
54
152
|
|
|
55
|
-
|
|
153
|
+
The plugin uses CSS custom properties for easy theming:
|
|
56
154
|
|
|
57
|
-
|
|
155
|
+
```css
|
|
156
|
+
.github-card {
|
|
157
|
+
--github-card-bg: #0d1117;
|
|
158
|
+
--github-card-border: #30363d;
|
|
159
|
+
--github-card-text: #e6edf3;
|
|
160
|
+
--github-card-text-secondary: #8b949e;
|
|
161
|
+
--github-card-link: #58a6ff;
|
|
162
|
+
--github-card-link-hover: #79c0ff;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Override these in your own CSS to match your site's design:
|
|
167
|
+
|
|
168
|
+
```css
|
|
169
|
+
.github-card {
|
|
170
|
+
--github-card-bg: var(--my-card-background);
|
|
171
|
+
--github-card-border: var(--my-border-color);
|
|
172
|
+
/* ... */
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Supported Languages
|
|
177
|
+
|
|
178
|
+
The plugin includes color mappings for 25+ popular programming languages. Unknown languages will use a default gray color.
|
|
179
|
+
|
|
180
|
+
## Development
|
|
181
|
+
|
|
182
|
+
After checking out the repo:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Install dependencies
|
|
186
|
+
bundle install
|
|
187
|
+
|
|
188
|
+
# Run tests
|
|
189
|
+
bundle exec rake test
|
|
190
|
+
|
|
191
|
+
# Build the gem
|
|
192
|
+
gem build jekyll-github-card.gemspec
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Running Tests
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
bundle exec rake test
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Contributing
|
|
202
|
+
|
|
203
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/r0x0d/jekyll-github-card.
|
|
204
|
+
|
|
205
|
+
1. Fork the repository
|
|
206
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
207
|
+
3. Commit your changes (`git commit -am 'Add amazing feature'`)
|
|
208
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
209
|
+
5. Open a Pull Request
|
|
58
210
|
|
|
59
211
|
## License
|
|
60
212
|
|
|
61
|
-
|
|
213
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
214
|
+
|
|
215
|
+
## Changelog
|
|
216
|
+
|
|
217
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
218
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rake/testtask"
|
|
5
|
+
|
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
|
7
|
+
t.libs << "test"
|
|
8
|
+
t.libs << "lib"
|
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
desc "Run tests"
|
|
13
|
+
task default: :test
|
|
14
|
+
|
data/assets/css/github-card.css
CHANGED
|
@@ -1,123 +1,185 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* Jekyll GitHub Card Styles
|
|
2
|
+
* Supports both light and dark themes
|
|
3
|
+
* For Chirpy theme: uses data-mode="light" for light, default for dark
|
|
4
|
+
*/
|
|
5
|
+
|
|
2
6
|
.github-card {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
--github-card-bg: #0d1117;
|
|
8
|
+
--github-card-border: #30363d;
|
|
9
|
+
--github-card-text: #e6edf3;
|
|
10
|
+
--github-card-text-secondary: #8b949e;
|
|
11
|
+
--github-card-link: #58a6ff;
|
|
12
|
+
--github-card-link-hover: #79c0ff;
|
|
13
|
+
--github-card-error-bg: #3d1f28;
|
|
14
|
+
--github-card-error-border: #f85149;
|
|
15
|
+
|
|
16
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
|
|
17
|
+
background-color: var(--github-card-bg);
|
|
18
|
+
border: 1px solid var(--github-card-border);
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
padding: 16px;
|
|
21
|
+
margin: 16px 0;
|
|
22
|
+
max-width: 480px;
|
|
23
|
+
box-sizing: border-box;
|
|
24
|
+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
.github-card:hover {
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
border-color: var(--github-card-link);
|
|
29
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Light theme support */
|
|
33
|
+
[data-mode="light"] .github-card,
|
|
34
|
+
.light .github-card,
|
|
35
|
+
[data-theme="light"] .github-card,
|
|
36
|
+
.github-card.light {
|
|
37
|
+
--github-card-bg: #ffffff;
|
|
38
|
+
--github-card-border: #d0d7de;
|
|
39
|
+
--github-card-text: #1f2328;
|
|
40
|
+
--github-card-text-secondary: #656d76;
|
|
41
|
+
--github-card-link: #0969da;
|
|
42
|
+
--github-card-link-hover: #0550ae;
|
|
43
|
+
--github-card-error-bg: #ffebe9;
|
|
44
|
+
--github-card-error-border: #cf222e;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[data-mode="light"] .github-card:hover,
|
|
48
|
+
.light .github-card:hover,
|
|
49
|
+
[data-theme="light"] .github-card:hover,
|
|
50
|
+
.github-card.light:hover {
|
|
51
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Prefer color scheme for automatic detection */
|
|
55
|
+
@media (prefers-color-scheme: light) {
|
|
56
|
+
.github-card:not([data-theme]):not(.dark) {
|
|
57
|
+
--github-card-bg: #ffffff;
|
|
58
|
+
--github-card-border: #d0d7de;
|
|
59
|
+
--github-card-text: #1f2328;
|
|
60
|
+
--github-card-text-secondary: #656d76;
|
|
61
|
+
--github-card-link: #0969da;
|
|
62
|
+
--github-card-link-hover: #0550ae;
|
|
63
|
+
--github-card-error-bg: #ffebe9;
|
|
64
|
+
--github-card-error-border: #cf222e;
|
|
65
|
+
}
|
|
19
66
|
}
|
|
20
67
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
color: #8b949e;
|
|
68
|
+
/* Header */
|
|
69
|
+
.github-card-header {
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
margin-bottom: 12px;
|
|
27
73
|
}
|
|
28
74
|
|
|
29
|
-
.github-card
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
75
|
+
.github-card-link {
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
gap: 8px;
|
|
79
|
+
color: var(--github-card-link);
|
|
80
|
+
text-decoration: none;
|
|
81
|
+
font-weight: 600;
|
|
82
|
+
font-size: 16px;
|
|
83
|
+
transition: color 0.2s ease;
|
|
34
84
|
}
|
|
35
85
|
|
|
36
|
-
.github-card
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
fill: #8b949e;
|
|
40
|
-
flex-shrink: 0;
|
|
41
|
-
transition: fill 0.2s ease;
|
|
86
|
+
.github-card-link:hover {
|
|
87
|
+
color: var(--github-card-link-hover);
|
|
88
|
+
text-decoration: underline;
|
|
42
89
|
}
|
|
43
90
|
|
|
44
|
-
.github-card
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
color: #58a6ff;
|
|
48
|
-
margin: 0;
|
|
49
|
-
transition: color 0.2s ease;
|
|
91
|
+
.github-card-icon {
|
|
92
|
+
flex-shrink: 0;
|
|
93
|
+
color: var(--github-card-text-secondary);
|
|
50
94
|
}
|
|
51
95
|
|
|
52
|
-
.github-card
|
|
53
|
-
|
|
54
|
-
color: #8b949e;
|
|
55
|
-
margin: 8px 0 12px 0;
|
|
56
|
-
line-height: 1.5;
|
|
57
|
-
transition: color 0.2s ease;
|
|
96
|
+
.github-card-repo-name {
|
|
97
|
+
word-break: break-word;
|
|
58
98
|
}
|
|
59
99
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
gap: 16px;
|
|
64
|
-
font-size: 12px;
|
|
65
|
-
color: #8b949e;
|
|
66
|
-
flex-wrap: wrap;
|
|
67
|
-
transition: color 0.2s ease;
|
|
100
|
+
/* Body */
|
|
101
|
+
.github-card-body {
|
|
102
|
+
margin-bottom: 12px;
|
|
68
103
|
}
|
|
69
104
|
|
|
70
|
-
.github-card
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
105
|
+
.github-card-description {
|
|
106
|
+
color: var(--github-card-text);
|
|
107
|
+
font-size: 14px;
|
|
108
|
+
line-height: 1.5;
|
|
109
|
+
margin: 0;
|
|
110
|
+
word-wrap: break-word;
|
|
111
|
+
overflow-wrap: break-word;
|
|
74
112
|
}
|
|
75
113
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
114
|
+
/* Footer */
|
|
115
|
+
.github-card-footer {
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: space-between;
|
|
119
|
+
flex-wrap: wrap;
|
|
120
|
+
gap: 12px;
|
|
81
121
|
}
|
|
82
122
|
|
|
83
|
-
.github-card
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
123
|
+
.github-card-language {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: 4px;
|
|
127
|
+
font-size: 12px;
|
|
128
|
+
color: var(--github-card-text-secondary);
|
|
87
129
|
}
|
|
88
130
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
131
|
+
.github-card-language-dot {
|
|
132
|
+
width: 12px;
|
|
133
|
+
height: 12px;
|
|
134
|
+
border-radius: 50%;
|
|
135
|
+
flex-shrink: 0;
|
|
94
136
|
}
|
|
95
137
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
138
|
+
.github-card-stats {
|
|
139
|
+
display: flex;
|
|
140
|
+
align-items: center;
|
|
141
|
+
gap: 16px;
|
|
99
142
|
}
|
|
100
143
|
|
|
101
|
-
|
|
102
|
-
|
|
144
|
+
.github-card-stat {
|
|
145
|
+
display: flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
gap: 4px;
|
|
148
|
+
font-size: 12px;
|
|
149
|
+
color: var(--github-card-text-secondary);
|
|
150
|
+
cursor: default;
|
|
103
151
|
}
|
|
104
152
|
|
|
105
|
-
|
|
106
|
-
|
|
153
|
+
.github-card-stat svg {
|
|
154
|
+
flex-shrink: 0;
|
|
155
|
+
color: var(--github-card-text-secondary);
|
|
107
156
|
}
|
|
108
157
|
|
|
109
|
-
|
|
110
|
-
|
|
158
|
+
/* Error state */
|
|
159
|
+
.github-card-error {
|
|
160
|
+
background-color: var(--github-card-error-bg);
|
|
161
|
+
border-color: var(--github-card-error-border);
|
|
111
162
|
}
|
|
112
163
|
|
|
113
|
-
|
|
114
|
-
|
|
164
|
+
.github-card-error:hover {
|
|
165
|
+
border-color: var(--github-card-error-border);
|
|
115
166
|
}
|
|
116
167
|
|
|
117
|
-
|
|
118
|
-
|
|
168
|
+
.github-card-error-message {
|
|
169
|
+
color: var(--github-card-error-border);
|
|
170
|
+
font-size: 14px;
|
|
171
|
+
margin: 0;
|
|
119
172
|
}
|
|
120
173
|
|
|
121
|
-
|
|
122
|
-
|
|
174
|
+
/* Responsive */
|
|
175
|
+
@media (max-width: 520px) {
|
|
176
|
+
.github-card {
|
|
177
|
+
max-width: 100%;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.github-card-footer {
|
|
181
|
+
flex-direction: column;
|
|
182
|
+
align-items: flex-start;
|
|
183
|
+
}
|
|
123
184
|
}
|
|
185
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module GithubCard
|
|
5
|
+
class StyleGenerator < Jekyll::Generator
|
|
6
|
+
safe true
|
|
7
|
+
priority :low
|
|
8
|
+
|
|
9
|
+
def generate(site)
|
|
10
|
+
css_content = File.read(File.join(File.dirname(__FILE__), "..", "..", "assets", "css", "github-card.css"))
|
|
11
|
+
|
|
12
|
+
# Create a static file for the CSS
|
|
13
|
+
site.static_files << StyleFile.new(site, css_content)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class StyleFile < Jekyll::StaticFile
|
|
18
|
+
def initialize(site, content)
|
|
19
|
+
@site = site
|
|
20
|
+
@content = content
|
|
21
|
+
@relative_path = "/assets/css/github-card.css"
|
|
22
|
+
@extname = ".css"
|
|
23
|
+
@name = "github-card.css"
|
|
24
|
+
@dir = "/assets/css"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def write(dest)
|
|
28
|
+
dest_path = File.join(dest, @relative_path)
|
|
29
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
30
|
+
File.write(dest_path, @content)
|
|
31
|
+
true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def path
|
|
35
|
+
@relative_path
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def relative_path
|
|
39
|
+
@relative_path
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
5
|
+
require "uri"
|
|
6
|
+
require "cgi"
|
|
7
|
+
|
|
8
|
+
module Jekyll
|
|
9
|
+
module GithubCard
|
|
10
|
+
class GithubRepoTag < Liquid::Tag
|
|
11
|
+
GITHUB_API_URL = "https://api.github.com/repos"
|
|
12
|
+
CACHE = {}
|
|
13
|
+
|
|
14
|
+
def initialize(tag_name, markup, tokens)
|
|
15
|
+
super
|
|
16
|
+
@repo = markup.strip
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def render(context)
|
|
20
|
+
return error_card("No repository specified") if @repo.empty?
|
|
21
|
+
|
|
22
|
+
repo_data = fetch_repo_data(@repo)
|
|
23
|
+
return error_card(repo_data[:error]) if repo_data[:error]
|
|
24
|
+
|
|
25
|
+
build_card(repo_data)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def fetch_repo_data(repo)
|
|
31
|
+
return CACHE[repo] if CACHE[repo]
|
|
32
|
+
|
|
33
|
+
uri = URI.parse("#{GITHUB_API_URL}/#{repo}")
|
|
34
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
35
|
+
http.use_ssl = true
|
|
36
|
+
http.open_timeout = 5
|
|
37
|
+
http.read_timeout = 5
|
|
38
|
+
|
|
39
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
40
|
+
request["Accept"] = "application/vnd.github.v3+json"
|
|
41
|
+
request["User-Agent"] = "Jekyll-Github-Card"
|
|
42
|
+
|
|
43
|
+
# Use GitHub token if available
|
|
44
|
+
if ENV["GITHUB_TOKEN"]
|
|
45
|
+
request["Authorization"] = "token #{ENV["GITHUB_TOKEN"]}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
response = http.request(request)
|
|
49
|
+
|
|
50
|
+
if response.code == "200"
|
|
51
|
+
data = JSON.parse(response.body)
|
|
52
|
+
CACHE[repo] = {
|
|
53
|
+
name: data["name"],
|
|
54
|
+
full_name: data["full_name"],
|
|
55
|
+
description: data["description"],
|
|
56
|
+
html_url: data["html_url"],
|
|
57
|
+
stargazers_count: data["stargazers_count"],
|
|
58
|
+
forks_count: data["forks_count"],
|
|
59
|
+
language: data["language"],
|
|
60
|
+
owner_avatar: data["owner"]["avatar_url"],
|
|
61
|
+
owner_login: data["owner"]["login"],
|
|
62
|
+
open_issues_count: data["open_issues_count"],
|
|
63
|
+
watchers_count: data["watchers_count"],
|
|
64
|
+
default_branch: data["default_branch"]
|
|
65
|
+
}
|
|
66
|
+
else
|
|
67
|
+
{ error: "Repository '#{repo}' not found (HTTP #{response.code})" }
|
|
68
|
+
end
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
{ error: "Failed to fetch repository: #{e.message}" }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def build_card(data)
|
|
74
|
+
escaped_description = CGI.escapeHTML(data[:description] || "No description available")
|
|
75
|
+
escaped_full_name = CGI.escapeHTML(data[:full_name])
|
|
76
|
+
escaped_language = CGI.escapeHTML(data[:language] || "")
|
|
77
|
+
|
|
78
|
+
<<~HTML
|
|
79
|
+
<div class="github-card" data-repo="#{escaped_full_name}">
|
|
80
|
+
<div class="github-card-header">
|
|
81
|
+
<a href="#{data[:html_url]}" target="_blank" rel="noopener noreferrer" class="github-card-link">
|
|
82
|
+
<svg class="github-card-icon" viewBox="0 0 16 16" width="20" height="20" aria-hidden="true">
|
|
83
|
+
<path fill="currentColor" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
|
|
84
|
+
</svg>
|
|
85
|
+
<span class="github-card-repo-name">#{escaped_full_name}</span>
|
|
86
|
+
</a>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="github-card-body">
|
|
89
|
+
<p class="github-card-description">#{escaped_description}</p>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="github-card-footer">
|
|
92
|
+
#{language_badge(escaped_language) if data[:language]}
|
|
93
|
+
<div class="github-card-stats">
|
|
94
|
+
<span class="github-card-stat" title="Stars">
|
|
95
|
+
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
|
|
96
|
+
<path fill="currentColor" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z"></path>
|
|
97
|
+
</svg>
|
|
98
|
+
#{format_number(data[:stargazers_count])}
|
|
99
|
+
</span>
|
|
100
|
+
<span class="github-card-stat" title="Forks">
|
|
101
|
+
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
|
|
102
|
+
<path fill="currentColor" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>
|
|
103
|
+
</svg>
|
|
104
|
+
#{format_number(data[:forks_count])}
|
|
105
|
+
</span>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
HTML
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def language_badge(language)
|
|
113
|
+
return "" if language.nil? || language.empty?
|
|
114
|
+
|
|
115
|
+
color = language_color(language)
|
|
116
|
+
<<~HTML
|
|
117
|
+
<span class="github-card-language">
|
|
118
|
+
<span class="github-card-language-dot" style="background-color: #{color}"></span>
|
|
119
|
+
#{language}
|
|
120
|
+
</span>
|
|
121
|
+
HTML
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def language_color(language)
|
|
125
|
+
colors = {
|
|
126
|
+
"Ruby" => "#701516",
|
|
127
|
+
"JavaScript" => "#f1e05a",
|
|
128
|
+
"TypeScript" => "#3178c6",
|
|
129
|
+
"Python" => "#3572A5",
|
|
130
|
+
"Java" => "#b07219",
|
|
131
|
+
"Go" => "#00ADD8",
|
|
132
|
+
"Rust" => "#dea584",
|
|
133
|
+
"C" => "#555555",
|
|
134
|
+
"C++" => "#f34b7d",
|
|
135
|
+
"C#" => "#178600",
|
|
136
|
+
"PHP" => "#4F5D95",
|
|
137
|
+
"Swift" => "#F05138",
|
|
138
|
+
"Kotlin" => "#A97BFF",
|
|
139
|
+
"Scala" => "#c22d40",
|
|
140
|
+
"Shell" => "#89e051",
|
|
141
|
+
"HTML" => "#e34c26",
|
|
142
|
+
"CSS" => "#563d7c",
|
|
143
|
+
"Vue" => "#41b883",
|
|
144
|
+
"React" => "#61dafb",
|
|
145
|
+
"Elixir" => "#6e4a7e",
|
|
146
|
+
"Clojure" => "#db5855",
|
|
147
|
+
"Haskell" => "#5e5086",
|
|
148
|
+
"Lua" => "#000080",
|
|
149
|
+
"Perl" => "#0298c3",
|
|
150
|
+
"R" => "#198CE7",
|
|
151
|
+
"Dart" => "#00B4AB",
|
|
152
|
+
"Objective-C" => "#438eff"
|
|
153
|
+
}
|
|
154
|
+
colors[language] || "#586069"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def format_number(num)
|
|
158
|
+
return "0" if num.nil?
|
|
159
|
+
|
|
160
|
+
if num >= 1_000_000
|
|
161
|
+
formatted = (num / 1_000_000.0).round(1)
|
|
162
|
+
formatted = formatted.to_i if formatted == formatted.to_i
|
|
163
|
+
"#{formatted}M"
|
|
164
|
+
elsif num >= 1_000
|
|
165
|
+
formatted = (num / 1_000.0).round(1)
|
|
166
|
+
formatted = formatted.to_i if formatted == formatted.to_i
|
|
167
|
+
"#{formatted}k"
|
|
168
|
+
else
|
|
169
|
+
num.to_s
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def error_card(message)
|
|
174
|
+
<<~HTML
|
|
175
|
+
<div class="github-card github-card-error">
|
|
176
|
+
<div class="github-card-body">
|
|
177
|
+
<p class="github-card-error-message">⚠️ #{CGI.escapeHTML(message)}</p>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
HTML
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
Liquid::Template.register_tag("github", Jekyll::GithubCard::GithubRepoTag)
|
|
187
|
+
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-github-card
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rodolfo Olivieri
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2025-12-12 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: jekyll
|
|
@@ -29,6 +30,20 @@ dependencies:
|
|
|
29
30
|
- - "<"
|
|
30
31
|
- !ruby/object:Gem::Version
|
|
31
32
|
version: '5.0'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: logger
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '1.5'
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.5'
|
|
32
47
|
- !ruby/object:Gem::Dependency
|
|
33
48
|
name: bundler
|
|
34
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -43,6 +58,20 @@ dependencies:
|
|
|
43
58
|
- - "~>"
|
|
44
59
|
- !ruby/object:Gem::Version
|
|
45
60
|
version: '2.0'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: minitest
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '5.0'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '5.0'
|
|
46
75
|
- !ruby/object:Gem::Dependency
|
|
47
76
|
name: rake
|
|
48
77
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -57,20 +86,36 @@ dependencies:
|
|
|
57
86
|
- - "~>"
|
|
58
87
|
- !ruby/object:Gem::Version
|
|
59
88
|
version: '13.0'
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: webmock
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '3.18'
|
|
96
|
+
type: :development
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.18'
|
|
103
|
+
description: Easily embed beautiful GitHub repository cards in your Jekyll site using
|
|
104
|
+
a simple Liquid tag. Supports light and dark themes.
|
|
63
105
|
email:
|
|
64
106
|
- rodolfo.olivieri3@gmail.com
|
|
65
107
|
executables: []
|
|
66
108
|
extensions: []
|
|
67
109
|
extra_rdoc_files: []
|
|
68
110
|
files:
|
|
111
|
+
- CHANGELOG.md
|
|
69
112
|
- LICENSE
|
|
70
113
|
- README.md
|
|
114
|
+
- Rakefile
|
|
71
115
|
- assets/css/github-card.css
|
|
72
|
-
-
|
|
73
|
-
- lib/jekyll-github-card/
|
|
116
|
+
- lib/jekyll-github-card.rb
|
|
117
|
+
- lib/jekyll-github-card/generator.rb
|
|
118
|
+
- lib/jekyll-github-card/tag.rb
|
|
74
119
|
- lib/jekyll-github-card/version.rb
|
|
75
120
|
homepage: https://github.com/r0x0d/jekyll-github-card
|
|
76
121
|
licenses:
|
|
@@ -79,6 +124,8 @@ metadata:
|
|
|
79
124
|
homepage_uri: https://github.com/r0x0d/jekyll-github-card
|
|
80
125
|
source_code_uri: https://github.com/r0x0d/jekyll-github-card
|
|
81
126
|
changelog_uri: https://github.com/r0x0d/jekyll-github-card/blob/main/CHANGELOG.md
|
|
127
|
+
rubygems_mfa_required: 'true'
|
|
128
|
+
post_install_message:
|
|
82
129
|
rdoc_options: []
|
|
83
130
|
require_paths:
|
|
84
131
|
- lib
|
|
@@ -86,14 +133,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
86
133
|
requirements:
|
|
87
134
|
- - ">="
|
|
88
135
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 2.
|
|
136
|
+
version: 2.7.0
|
|
90
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
138
|
requirements:
|
|
92
139
|
- - ">="
|
|
93
140
|
- !ruby/object:Gem::Version
|
|
94
141
|
version: '0'
|
|
95
142
|
requirements: []
|
|
96
|
-
rubygems_version: 3.
|
|
143
|
+
rubygems_version: 3.4.19
|
|
144
|
+
signing_key:
|
|
97
145
|
specification_version: 4
|
|
98
|
-
summary: A Jekyll plugin to display
|
|
146
|
+
summary: A Jekyll plugin to display GitHub repository cards in your posts
|
|
99
147
|
test_files: []
|
data/assets/js/github-card.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
window.createGitHubCard = async function(elementId, repo) {
|
|
2
|
-
const element = document.getElementById(elementId);
|
|
3
|
-
|
|
4
|
-
if (!element) {
|
|
5
|
-
console.error('GitHub Card: Element with id "' + elementId + '" not found');
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
element.className = 'github-card loading';
|
|
10
|
-
element.innerHTML = 'Loading repository...';
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
const response = await fetch('https://api.github.com/repos/' + repo);
|
|
14
|
-
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
throw new Error('Repository not found');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const data = await response.json();
|
|
20
|
-
|
|
21
|
-
function formatCount(count) {
|
|
22
|
-
if (count >= 1000) {
|
|
23
|
-
return (count / 1000).toFixed(1) + 'k';
|
|
24
|
-
}
|
|
25
|
-
return count.toString();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const languageColors = {
|
|
29
|
-
'JavaScript': '#f1e05a',
|
|
30
|
-
'TypeScript': '#3178c6',
|
|
31
|
-
'Python': '#3572A5',
|
|
32
|
-
'Java': '#b07219',
|
|
33
|
-
'Ruby': '#701516',
|
|
34
|
-
'Go': '#00ADD8',
|
|
35
|
-
'Rust': '#dea584',
|
|
36
|
-
'C++': '#f34b7d',
|
|
37
|
-
'C': '#555555',
|
|
38
|
-
'PHP': '#4F5D95',
|
|
39
|
-
'Swift': '#F05138',
|
|
40
|
-
'Kotlin': '#A97BFF',
|
|
41
|
-
'HTML': '#e34c26',
|
|
42
|
-
'CSS': '#563d7c',
|
|
43
|
-
'Shell': '#89e051',
|
|
44
|
-
'Dart': '#00B4AB',
|
|
45
|
-
'Scala': '#c22d40'
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const languageColor = languageColors[data.language] || '#858585';
|
|
49
|
-
|
|
50
|
-
function escapeHtml(text) {
|
|
51
|
-
const div = document.createElement('div');
|
|
52
|
-
div.textContent = text;
|
|
53
|
-
return div.innerHTML;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
element.className = 'github-card';
|
|
57
|
-
element.innerHTML =
|
|
58
|
-
'<div class="card-header">' +
|
|
59
|
-
'<svg class="github-icon" viewBox="0 0 16 16">' +
|
|
60
|
-
'<path d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>' +
|
|
61
|
-
'</svg>' +
|
|
62
|
-
'<h3 class="repo-name">' + escapeHtml(data.full_name) + '</h3>' +
|
|
63
|
-
'</div>' +
|
|
64
|
-
'<p class="description">' +
|
|
65
|
-
escapeHtml(data.description || 'No description provided') +
|
|
66
|
-
'</p>' +
|
|
67
|
-
'<div class="card-footer">' +
|
|
68
|
-
'<span class="stat">' +
|
|
69
|
-
'<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">' +
|
|
70
|
-
'<path d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z"></path>' +
|
|
71
|
-
'</svg>' +
|
|
72
|
-
formatCount(data.stargazers_count) +
|
|
73
|
-
'</span>' +
|
|
74
|
-
'<span class="stat">' +
|
|
75
|
-
'<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">' +
|
|
76
|
-
'<path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75v-.878a2.25 2.25 0 111.5 0v.878a2.25 2.25 0 01-2.25 2.25h-1.5v2.128a2.251 2.251 0 11-1.5 0V8.5h-1.5A2.25 2.25 0 013 6.25v-.878a2.25 2.25 0 111.5 0zM5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm6.75.75a.75.75 0 100-1.5.75.75 0 000 1.5zm-3 8.75a.75.75 0 11-1.5 0 .75.75 0 011.5 0z"></path>' +
|
|
77
|
-
'</svg>' +
|
|
78
|
-
formatCount(data.forks_count) +
|
|
79
|
-
'</span>' +
|
|
80
|
-
(data.language ?
|
|
81
|
-
'<span class="stat">' +
|
|
82
|
-
'<span class="language-dot" style="background-color: ' + languageColor + ';"></span>' +
|
|
83
|
-
escapeHtml(data.language) +
|
|
84
|
-
'</span>'
|
|
85
|
-
: '') +
|
|
86
|
-
'</div>';
|
|
87
|
-
|
|
88
|
-
element.style.cursor = 'pointer';
|
|
89
|
-
element.onclick = function() {
|
|
90
|
-
window.open(data.html_url, '_blank');
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
} catch (error) {
|
|
94
|
-
element.className = 'github-card';
|
|
95
|
-
element.innerHTML = '<p class="error-message">Failed to load repository: ' + escapeHtml(repo) + '</p>';
|
|
96
|
-
console.error('GitHub Card Error:', error);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function escapeHtml(text) {
|
|
100
|
-
const div = document.createElement('div');
|
|
101
|
-
div.textContent = text;
|
|
102
|
-
return div.innerHTML;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "jekyll-github-card/version"
|
|
4
|
-
|
|
5
|
-
module Jekyll
|
|
6
|
-
module GitHubCard
|
|
7
|
-
class Error < StandardError; end
|
|
8
|
-
|
|
9
|
-
# Tag for {% github owner/repo %}
|
|
10
|
-
class GitHubCardTag < Liquid::Tag
|
|
11
|
-
def initialize(tag_name, text, tokens)
|
|
12
|
-
super
|
|
13
|
-
@repo = text.strip
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def render(context)
|
|
17
|
-
# Generate a unique ID from the repo name
|
|
18
|
-
id = @repo.gsub('/', '-').gsub(/[^a-zA-Z0-9\-]/, '')
|
|
19
|
-
|
|
20
|
-
<<~HTML
|
|
21
|
-
<div id="github-card-#{id}" class="github-card loading">Loading repository...</div>
|
|
22
|
-
<script>
|
|
23
|
-
(function() {
|
|
24
|
-
function initCard() {
|
|
25
|
-
if (typeof createGitHubCard === 'function') {
|
|
26
|
-
createGitHubCard('github-card-#{id}', '#{@repo}');
|
|
27
|
-
} else {
|
|
28
|
-
setTimeout(initCard, 100);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (document.readyState === 'loading') {
|
|
33
|
-
document.addEventListener('DOMContentLoaded', initCard);
|
|
34
|
-
} else {
|
|
35
|
-
initCard();
|
|
36
|
-
}
|
|
37
|
-
})();
|
|
38
|
-
</script>
|
|
39
|
-
HTML
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Generator to copy assets to site
|
|
44
|
-
class AssetsGenerator < Jekyll::Generator
|
|
45
|
-
safe true
|
|
46
|
-
priority :low
|
|
47
|
-
|
|
48
|
-
def generate(site)
|
|
49
|
-
# Get the gem's asset directory
|
|
50
|
-
gem_dir = File.expand_path("../../", __dir__)
|
|
51
|
-
assets_dir = File.join(gem_dir, "assets")
|
|
52
|
-
|
|
53
|
-
return unless File.directory?(assets_dir)
|
|
54
|
-
|
|
55
|
-
# Copy CSS
|
|
56
|
-
css_source = File.join(assets_dir, "css", "github-card.css")
|
|
57
|
-
css_dest = File.join(site.source, "assets", "css", "github-card.css")
|
|
58
|
-
|
|
59
|
-
if File.exist?(css_source)
|
|
60
|
-
FileUtils.mkdir_p(File.dirname(css_dest))
|
|
61
|
-
FileUtils.cp(css_source, css_dest)
|
|
62
|
-
site.static_files << Jekyll::StaticFile.new(
|
|
63
|
-
site,
|
|
64
|
-
site.source,
|
|
65
|
-
"assets/css",
|
|
66
|
-
"github-card.css"
|
|
67
|
-
)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Copy JS
|
|
71
|
-
js_source = File.join(assets_dir, "js", "github-card.js")
|
|
72
|
-
js_dest = File.join(site.source, "assets", "js", "github-card.js")
|
|
73
|
-
|
|
74
|
-
if File.exist?(js_source)
|
|
75
|
-
FileUtils.mkdir_p(File.dirname(js_dest))
|
|
76
|
-
FileUtils.cp(js_source, js_dest)
|
|
77
|
-
site.static_files << Jekyll::StaticFile.new(
|
|
78
|
-
site,
|
|
79
|
-
site.source,
|
|
80
|
-
"assets/js",
|
|
81
|
-
"github-card.js"
|
|
82
|
-
)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
Liquid::Template.register_tag('github', Jekyll::GitHubCard::GitHubCardTag)
|