Skip to content

Commit 9d761e4

Browse files
authored
Update v1.16.0 (#40)
### Features - **feat: add new blog post (xFvj4iCr) (en/pt)** - feat: add option to disable image zoom - feat: add `listenToGallery` to browser scripts - feat(plugins): add option to external mention - feat: add `remark-mermaid` plugin - feat: add `remark-image-host` plugin ### Changes - refactor(plugins): replace `remark-slider` with `remark-gallery` - refactor(style): update medium-zoom z-index ### Issues - fix: wrong `Logo` component size *Bump version to 1.16.0*
1 parent c058b68 commit 9d761e4

33 files changed

+2565
-254
lines changed

astro.config.mjs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ import remarkToc from 'remark-toc';
2424
import remarkAlertBlocks from './plugins/remark-alert-blocks';
2525
import remarkAutoSelect from './plugins/remark-auto-select';
2626
import remarkCodeSet from './plugins/remark-code-set';
27+
import remarkGallery from './plugins/remark-gallery';
2728
import remarkGitHubCard from './plugins/remark-github-card';
2829
import remarkImageCaption from './plugins/remark-image-caption';
30+
import remarkImageHost from './plugins/remark-image-host';
2931
import remarkMention from './plugins/remark-mention';
30-
import remarkSlider from './plugins/remark-slider';
32+
import remarkMermaid from './plugins/remark-mermaid';
3133
import remarkTextHighlight from './plugins/remark-text-highlight';
3234

3335
import { defaultLocale, explicitLocales, locales } from './src/i18n/config';
@@ -189,15 +191,25 @@ export default defineConfig({
189191
],
190192
],
191193
remarkPlugins: [
194+
[
195+
remarkImageHost,
196+
{
197+
imageBaseUrl:
198+
process.env.CONTEXT === 'production'
199+
? 'https://rawcdn.githack.com/lucjosin/lucasjosino.com/main/public'
200+
: '',
201+
},
202+
],
192203
remarkDirective,
193204
remarkAutoSelect,
194205
remarkMention,
206+
remarkGallery,
195207
remarkLinkCard,
196208
remarkGitHubCard,
209+
remarkMermaid,
197210
numberedFootnoteLabels,
198211
remarkAlertBlocks,
199212
remarkTextHighlight,
200-
remarkSlider,
201213
remarkImageCaption,
202214
responsiveTables,
203215
remarkCodeSet,

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@lucjosin/lucasjosino.com",
33
"packageManager": "[email protected]",
4-
"version": "1.14.1",
4+
"version": "1.16.0",
55
"private": true,
66
"scripts": {
77
"dev": "astro dev",
@@ -59,6 +59,7 @@
5959
"@xt0rted/expressive-code-file-icons": "^1.0.0",
6060
"astro-meta-tags": "^0.3.1",
6161
"medium-zoom": "^1.1.0",
62+
"mermaid": "^11.6.0",
6263
"react": "^18.3.1",
6364
"react-dom": "^18.3.1",
6465
"reading-time": "^1.5.0"

plugins/remark-gallery.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { visit } from 'unist-util-visit';
2+
3+
/** @type {import("unified").Plugin<[], import("mdast").Root>} */
4+
export default function remarkGallery() {
5+
return (tree) => {
6+
visit(tree, (node) => {
7+
if (node.type === 'containerDirective' && node.name === 'gallery') {
8+
const images = node.children
9+
.filter((child) => child.type === 'paragraph')
10+
.flatMap((p) => p.children?.filter((c) => c.type === 'image') || []);
11+
12+
const imageData = images.map((img, index) => ({
13+
url: img.url,
14+
alt: img.alt || `Image ${index + 1}`,
15+
index,
16+
}));
17+
18+
node.data = {
19+
hName: 'div',
20+
hProperties: { className: 'gallery-wrapper', 'data-gallery': true },
21+
hChildren: [
22+
{
23+
type: 'element',
24+
tagName: 'div',
25+
properties: { className: 'gallery-main' },
26+
children: [
27+
{
28+
type: 'element',
29+
tagName: 'figure',
30+
properties: {
31+
className: 'gallery-main-figure',
32+
},
33+
children: [
34+
{
35+
type: 'element',
36+
tagName: 'button',
37+
properties: {
38+
className: 'gallery-prev',
39+
type: 'button',
40+
'aria-label': 'Previous image',
41+
},
42+
children: [{ type: 'text', value: '←' }],
43+
},
44+
{
45+
type: 'element',
46+
tagName: 'button',
47+
properties: {
48+
className: 'gallery-next',
49+
type: 'button',
50+
'aria-label': 'Next image',
51+
},
52+
children: [{ type: 'text', value: '→' }],
53+
},
54+
{
55+
type: 'element',
56+
tagName: 'img',
57+
properties: {
58+
className: 'gallery-active-img',
59+
src: imageData[0]?.url,
60+
alt: imageData[0]?.alt || '',
61+
title: imageData[0]?.alt || '',
62+
},
63+
children: [],
64+
},
65+
{
66+
type: 'element',
67+
tagName: 'figcaption',
68+
properties: {},
69+
children: [
70+
{ type: 'text', value: imageData[0]?.alt || '' },
71+
{ type: 'text', value: ' - ' },
72+
{
73+
type: 'element',
74+
tagName: 'a',
75+
properties: {
76+
href: imageData[0]?.url || '',
77+
title: 'Click to open image in a new tab',
78+
target: '_blank',
79+
rel: 'noopener noreferrer',
80+
},
81+
children: [
82+
{ type: 'text', value: 'View image in a new tab' },
83+
],
84+
},
85+
],
86+
},
87+
],
88+
},
89+
],
90+
},
91+
{
92+
type: 'element',
93+
tagName: 'div',
94+
properties: { className: 'gallery-thumbs' },
95+
children: imageData.map(({ url, alt, index }) => ({
96+
type: 'element',
97+
tagName: 'img',
98+
properties: {
99+
src: url,
100+
alt,
101+
className:
102+
index === 0 ? 'thumb active no-zoom' : 'thumb no-zoom',
103+
'data-index': index,
104+
},
105+
children: [],
106+
})),
107+
},
108+
],
109+
};
110+
}
111+
});
112+
};
113+
}

plugins/remark-image-host.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { visit } from 'unist-util-visit';
2+
3+
export default function remarkImageHost(options) {
4+
const imageBaseUrl = options?.imageBaseUrl?.replace(/\/+$/, '');
5+
6+
if (!imageBaseUrl) {
7+
console.log('[remark-image-host] No host provided. Using default.');
8+
}
9+
10+
return (tree) => {
11+
visit(tree, 'image', (node) => {
12+
if (
13+
typeof node.url === 'string' &&
14+
node.url.includes('{{image_base_url}}')
15+
) {
16+
node.url = node.url.replace('{{image_base_url}}', imageBaseUrl);
17+
}
18+
});
19+
};
20+
}

plugins/remark-mention.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,29 @@ export default function remarkMention() {
77
const { name, attributes } = node;
88

99
if (name === 'mention') {
10+
let rel = attributes.rel || 'noopener noreferrer';
11+
let target = attributes.target || '_blank';
1012
const url = attributes.url;
13+
const external = attributes.external || true;
1114
const img = attributes.img;
1215
const label = node.children?.[0]?.value || '';
1316

17+
if (!external) {
18+
target = '_self';
19+
rel = '';
20+
}
21+
1422
if (!url) return;
1523

1624
const finalImage =
1725
img ||
1826
`https://www.google.com/s2/favicons?domain=${new URL(url).hostname}`;
1927

2028
node.type = 'html';
21-
node.value = `<a href="${url}" class="remark-mention">
29+
node.value = `<a href="${url}" class="remark-mention" target="${target}" rel="${rel}">
2230
<img src="${finalImage}" alt="${label}" class="remark-mention-icon" width="16" height="16" />
2331
<span>${node.children.map((child) => child.value).join('')}</span>
32+
${external ? `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M14 3v2h3.59l-9.83 9.83l1.41 1.41L19 6.41V10h2V3m-2 16H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7h-2v7Z" /></svg>` : ''}
2433
</a>`;
2534
}
2635
}

plugins/remark-mermaid.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// https://github.com/paularmstrong/onerepo/blob/main/docs/src/plugins/remark-mermaid.ts
2+
3+
import { visit } from 'unist-util-visit';
4+
5+
const escapeMap = {
6+
'&': '&amp;',
7+
'<': '&lt;',
8+
'>': '&gt;',
9+
'"': '&quot;',
10+
"'": '&#39;',
11+
'\n': '%0A',
12+
};
13+
14+
const escapeHtml = (str) => str.replace(/[&<>"']/g, (c) => escapeMap[c] ?? c);
15+
16+
export default function remarkMermaid() {
17+
return (tree) => {
18+
visit(tree, 'code', (node) => {
19+
if (node.lang === 'mermaid') {
20+
node.type = 'html';
21+
node.value = `<div class="mermaid" data-content="${escapeHtml(node.value)}"><p>Loading graph...</p></div>`;
22+
}
23+
});
24+
};
25+
}

plugins/remark-slider.js

Lines changed: 0 additions & 142 deletions
This file was deleted.
794 KB
Loading
245 KB
Loading
251 KB
Loading

0 commit comments

Comments
 (0)