Skip to content

Commit c069ee5

Browse files
committed
feat(github-card): Display a nice card on github repo links
1 parent 9caf10f commit c069ee5

11 files changed

+266
-8
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ The website integrates the following layouts:
8686
- [Font Awesome 5](https://fontawesome.com/v5.15/how-to-use/on-the-web/setup/using-package-managers): A widely-used icon set and toolkit.
8787
- [Google Fonts](https://fonts.google.com): A library of 1,000 free, open-source fonts.
8888
- [Compress HTML](https://github.com/penibelst/jekyll-compress-html): A plugin for HTML compression.
89-
- Code snippet highlighting (Jekyll integrated syntax highlighter, styled like [Carbon Now](https://carbon.now.sh/) images).
89+
- Code snippet highlighting: A Jekyll integrated syntax highlighter, styled like [Carbon Now](https://carbon.now.sh/) images.
90+
- GitHub Card: A Jekyll tag, displaying GitHub repo details as GitHub does.
9091

9192
## Utilizes Jekyll Themes
9293

_plugins/jekyll-github-card.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module Jekyll
2+
class GitHubCard < Liquid::Tag
3+
def initialize(tag_name, text, tokens)
4+
super
5+
@repo_name = text.strip
6+
end
7+
8+
9+
def render(context)
10+
# Generate HTML with SVG icons
11+
result = "<div class='github-card clearfix panel panel-default'>"
12+
result << " <div class='panel-body'>"
13+
result << " <div class='name'>#{octo_icon} <a href='https://github.com/#{@repo_name}' target='_blank' rel='noopener noreferrer nofollow'>#{@repo_name}</a>&nbsp;<span class='label'>Public</span></div>"
14+
result << " </div>"
15+
result << "</div>"
16+
end
17+
18+
private
19+
20+
# GitHub mark SVG icon
21+
# https://primer.style/foundations/icons/mark-github-16
22+
def octo_icon
23+
<<-SVG
24+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path></svg>
25+
SVG
26+
end
27+
end
28+
end
29+
30+
Liquid::Template.register_tag('github_card', Jekyll::GitHubCard)

_posts/2023-12-29-mixtral-ollama-llamaindex-llm.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ une démocratisation de ces technologies.
8888

8989
Pour installer Ollama sur votre poste :
9090

91-
- Allez sur le projet Github et suivez les instructions [https://github.com/jmorganca/ollama](https://github.com/jmorganca/ollama){:target="_blank" rel="noopener noreferrer nofollow"}.
91+
- Allez sur le projet Github et suivez les instructions :
92+
{% github_card ollama/ollama %}
9293
- Ou bien téléchargez directement le binaire d'installation de Ollama [https://ollama.ai/download](https://ollama.ai/download){:target="_blank" rel="noopener noreferrer nofollow"}
9394
et lancez son installation sur votre poste.
9495

_posts/2024-01-07-ferret-apple-mac-llm.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ git lfs install
6161
### Étape 2 : Télécharger le Code Source de Ferret
6262

6363
J'ai adapté le code de Ferret pour les processeurs Silicon et le framework Metal Performance Shaders (MPS) d'Apple. Il
64-
est disponible sur [https://github.com/jeanjerome/ml-ferret/tree/silicon](https://github.com/jeanjerome/ml-ferret/tree/silicon){:target="_blank" rel="noopener noreferrer nofollow"} :
64+
est disponible sur ce repo :
65+
{% github_card jeanjerome/ml-ferret %}
6566

6667
- La branche **_main_** contient le code d'origine d'Apple.
6768
- La branche **_silicon_** contient ma version adaptée.

_posts/2024-02-11-crewai-mixtral-agile-team.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ remplacer.
100100

101101
### Code Source
102102

103-
Vous trouverez le code source de ce projet dans le repo GitHub [https://github.com/jeanjerome/ai-agile-team](https://github.com/jeanjerome/ai-agile-team){:target="_blank" rel="noopener noreferrer nofollow"}
103+
Vous trouverez le code source de ce projet dans ce repo GitHub :
104+
{% github_card jeanjerome/ai-agile-team %}
104105

105106
<hr class="hr-text" data-content="Agents">
106107

_posts/en/2023-12-29-mixtral-ollama-llamaindex-llm.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ the democratization of these technologies.
9090

9191
To install Ollama on your computer:
9292

93-
- Go to the GitHub project and follow the instructions [https://github.com/jmorganca/ollama](https://github.com/jmorganca/ollama){:target="_blank" rel="noopener noreferrer nofollow"}.
93+
- Go to the GitHub project and follow the instructions:
94+
{% github_card ollama/ollama %}
9495
- Or download the Ollama installation binary directly from [https://ollama.ai/download](https://ollama.ai/download){:target="_blank" rel="noopener noreferrer nofollow"}
9596
and start the installation on your computer.
9697

_posts/en/2024-01-07-ferret-apple-mac-llm.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ git lfs install
6161
### Step 2: Download Ferret's Source Code
6262

6363
I've adapted the Ferret code for Silicon processors and Apple's Metal Performance Shaders (MPS) framework. It
64-
is available at [https://github.com/jeanjerome/ml-ferret/tree/silicon](https://github.com/jeanjerome/ml-ferret/tree/silicon){:target="_blank" rel="noopener noreferrer nofollow"} :
64+
is available on this repo:
65+
{% github_card jeanjerome/ml-ferret %}
6566

6667
- The **_main_** branch contains the original code from Apple.
6768
- The **_silicon_** branch contains my adapted version.

_posts/en/2024-02-11-crewai-mixtral-agile-team.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ and enrich human capabilities rather than merely replace them.
9494

9595
### Source Code
9696

97-
You can find the source code for this project in the GitHub repo [https://github.com/jeanjerome/ai-agile-team](https://github.com/jeanjerome/ai-agile-team){:target="_blank" rel="noopener noreferrer nofollow"}
97+
You can find the source code for this project in this GitHub repo:
98+
{% github_card jeanjerome/ai-agile-team %}
9899

99100
<hr class="hr-text" data-content="Agents">
100101

_sass/_premonition.scss

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,116 @@ $svg-citation-color: "495057";
156156
}
157157
/* End of Autogenerated code */
158158
}
159+
160+
// GitHub Card
161+
.github-card {
162+
color: #59636e;
163+
background: #ffffff;
164+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
165+
font-size: 14px;
166+
border: 1px solid #d0d7de;
167+
border-radius: 10px;
168+
padding: 16px;
169+
margin-bottom: 20px;
170+
width: 100%;
171+
max-width: 600px;
172+
173+
/* Centrage horizontal */
174+
margin: 0 auto;
175+
176+
display: flex;
177+
flex-direction: column;
178+
//justify-content: center;
179+
//align-items: center;
180+
181+
.panel-body {
182+
padding: 12px;
183+
}
184+
185+
.name {
186+
display: flex;
187+
align-items: center;
188+
font-size: 20px;
189+
font-weight: 600;
190+
margin-bottom: 10px;
191+
192+
svg {
193+
margin-right: 8px;
194+
}
195+
196+
a {
197+
color: #0969da;
198+
text-decoration: none;
199+
&:after {
200+
content: none;
201+
}
202+
&:hover {
203+
text-decoration: underline;
204+
}
205+
}
206+
}
207+
208+
.label {
209+
border-color: #d1d9e0;
210+
color: #59636e;
211+
border: max(1px, 0.0625rem) solid #d1d9e0;
212+
border-radius: 624.9375rem;
213+
display: inline-block;
214+
font-size: 0.75rem;
215+
font-weight: 500;
216+
line-height: 18px;
217+
padding: 0 0.375rem;
218+
white-space: nowrap;
219+
}
220+
221+
.description {
222+
font-size: 14px;
223+
color: #59636e;
224+
margin-bottom: 10px;
225+
}
226+
227+
.badge-group {
228+
margin-top: 10px;
229+
display: flex;
230+
flex-wrap: wrap;
231+
232+
.badge {
233+
margin: 0 .125em .333em 0;
234+
display: inline-block;
235+
padding: 0 7px;
236+
font-size: 12px;
237+
font-weight: 500;
238+
line-height: 18px;
239+
white-space: nowrap;
240+
border: 1px solid transparent;
241+
border-radius: 2em;
242+
padding-right: 10px;
243+
padding-left: 10px;
244+
line-height: 22px;
245+
color: #0969da;
246+
background-color: #ddf4ff;
247+
border: max(1px, 0.0625rem) solid transparent;
248+
}
249+
}
250+
251+
.stats {
252+
display: flex;
253+
align-items: center;
254+
font-size: 14px;
255+
color: #57606a;
256+
margin-top: max(0.5rem, 8px) !important;
257+
258+
svg {
259+
display: inline-block;
260+
overflow: visible !important;
261+
vertical-align: text-bottom;
262+
fill: currentColor;
263+
margin-right: max(0.25rem, 4px) !important;
264+
}
265+
266+
span {
267+
margin-right: max(1rem, 16px) !important;
268+
}
269+
}
270+
271+
}

darkmode.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,105 @@ function scrollToTop() {
123123
}
124124

125125
rocket(1000);
126+
127+
// GitHub Card
128+
document.addEventListener('DOMContentLoaded', async () => {
129+
const repoName = document.querySelector('.github-card .name a').textContent.trim();
130+
131+
// Function to format large numbers (e.g., 92869 -> 92.9k)
132+
function formatNumber(num) {
133+
if (num >= 1000) {
134+
return (num / 1000).toFixed(1) + 'k';
135+
}
136+
return num.toString();
137+
}
138+
139+
// Fetch the informations repo
140+
async function fetchRepoData(repo) {
141+
try {
142+
const response = await fetch(`https://api.github.com/repos/${repo}`);
143+
if (!response.ok) {
144+
throw new Error(`HTTP error! status: ${response.status}`);
145+
}
146+
return await response.json();
147+
} catch (error) {
148+
console.warn(`Failed to fetch data for ${repo}: ${error.message}`);
149+
return null;
150+
}
151+
}
152+
153+
// Complete the existing HTML
154+
async function completeGitHubCard() {
155+
const repo = await fetchRepoData(repoName);
156+
157+
if (repo) {
158+
const {
159+
full_name: fullName,
160+
description,
161+
stargazers_count: stars,
162+
forks_count: forks,
163+
pushed_at: pushedAt,
164+
language,
165+
license,
166+
topics = []
167+
} = repo;
168+
169+
// Date formatter
170+
const formattedDate = new Date(pushedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
171+
172+
// Inject new data into the card
173+
const card = document.querySelector('.github-card .panel-body');
174+
175+
// Inject description
176+
const descriptionHtml = document.createElement('div');
177+
descriptionHtml.className = 'description';
178+
descriptionHtml.textContent = description;
179+
card.appendChild(descriptionHtml);
180+
181+
// Injects topics
182+
if (topics.length > 0) {
183+
const topicsHtml = document.createElement('div');
184+
topicsHtml.className = 'badge-group';
185+
topicsHtml.innerHTML = topics.map(topic => `<span class='badge'>${topic}</span>`).join(' ');
186+
card.appendChild(topicsHtml);
187+
}
188+
189+
// Inject statistics (language, stars, forks, license, last push as last update)
190+
const statsHtml = document.createElement('div');
191+
statsHtml.className = 'stats';
192+
statsHtml.innerHTML = `
193+
<span>${languageIcon()} ${language || 'Unknown Language'}</span>
194+
<span>${starIcon()} ${formatNumber(stars)}</span>
195+
<span>${forkIcon()} ${formatNumber(forks)}</span>
196+
<span>${licenseIcon()} ${license?.name || 'No License'}</span>
197+
<span>Updated on ${formattedDate}</span>
198+
`;
199+
card.appendChild(statsHtml);
200+
}
201+
}
202+
203+
// Run the function to complete the card
204+
completeGitHubCard();
205+
});
206+
207+
// Icons come from official https://primer.style/foundations/icons
208+
209+
// https://primer.style/foundations/icons/file-binary-16
210+
function languageIcon() {
211+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2a.75.75 0 0 1-1.5 0Zm-4 6C0 6.784.784 6 1.75 6h1.5C4.216 6 5 6.784 5 7.75v2.5A1.75 1.75 0 0 1 3.25 12h-1.5A1.75 1.75 0 0 1 0 10.25ZM6.75 6h1.5a.75.75 0 0 1 .75.75v3.75h.75a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5h.75v-3h-.75a.75.75 0 0 1 0-1.5Zm-5 1.5a.25.25 0 0 0-.25.25v2.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-2.5a.25.25 0 0 0-.25-.25Zm9.75-5.938V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg>`;
212+
}
213+
214+
// https://primer.style/foundations/icons/star-16
215+
function starIcon() {
216+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path></svg>`;
217+
}
218+
219+
// https://primer.style/foundations/icons/repo-forked-16
220+
function forkIcon() {
221+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path></svg>`;
222+
}
223+
224+
// https://primer.style/foundations/icons/law-16
225+
function licenseIcon() {
226+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"></path></svg>`;
227+
}

0 commit comments

Comments
 (0)