Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
92830b0
Update links
PuruVJ Feb 16, 2023
67e3f85
Move blog to site/content
PuruVJ Feb 16, 2023
3a7c72a
Update site/content/docs/02-component-format.md
Rich-Harris Feb 20, 2023
f035690
Merge remote-tracking branch 'origin/sites' into feat/update-content
PuruVJ Mar 8, 2023
661a1dd
Fix docs links
PuruVJ Mar 8, 2023
7efb26b
Add global prettierrc
PuruVJ Mar 18, 2023
90539fe
Auto format
PuruVJ Mar 18, 2023
e3873e8
Merge remote-tracking branch 'origin/sites' into feat/update-content
PuruVJ Mar 18, 2023
938c6f9
Fix git merge artifact
PuruVJ Mar 18, 2023
2227f73
Fix errors
PuruVJ Mar 18, 2023
11a0b47
Merge branch 'sites' into feat/update-content
PuruVJ Mar 28, 2023
d7c1a95
Update html to svelte(remaining ones)
PuruVJ Mar 28, 2023
ed377c6
Add 2 blog posts
PuruVJ Mar 28, 2023
a2df8fe
Merge remote-tracking branch 'origin/sites' into feat/update-content
PuruVJ Mar 28, 2023
1a4d484
Merge branch 'sites' into feat/update-content
PuruVJ Mar 28, 2023
19f79c3
Modify prettierrc
PuruVJ Mar 28, 2023
58293a1
Minor design fix
PuruVJ Mar 29, 2023
b8c0722
Switch package lock to spaces, prettier ignore
PuruVJ Mar 29, 2023
2e2bacb
Merge remote-tracking branch 'origin/sites' into feat/update-content
PuruVJ Mar 30, 2023
5da78e3
Regenerate package lock
PuruVJ Mar 30, 2023
47709f0
prettier format
PuruVJ Mar 30, 2023
fef232f
Update deps
PuruVJ Mar 31, 2023
fe5781f
Merge branch 'sites' into feat/redo-blog-logic
PuruVJ Apr 3, 2023
7809dea
Redo
PuruVJ Apr 3, 2023
069f5b4
Fix errors
PuruVJ Apr 3, 2023
4138593
Reinstall package lock
PuruVJ Apr 3, 2023
b176353
Misc
PuruVJ Apr 3, 2023
2dac3bf
Merge remote-tracking branch 'origin/sites' into feat/redo-blog-logic
PuruVJ Apr 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,310 changes: 1,088 additions & 222 deletions sites/svelte.dev/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion sites/svelte.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@resvg/resvg-js": "^2.4.1",
"@sveltejs/adapter-vercel": "^2.4.1",
"@sveltejs/kit": "^1.15.0",
"@sveltejs/site-kit": "^3.3.6",
"@sveltejs/site-kit": "^3.3.7",
"@sveltejs/vite-plugin-svelte": "^2.0.4",
"@types/marked": "^4.0.8",
"@types/prismjs": "^1.26.0",
Expand Down
60 changes: 60 additions & 0 deletions sites/svelte.dev/src/lib/server/blog/get-blog-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// @ts-check
import fs from 'fs';
import { extract_frontmatter } from '../markdown';

const BLOG_NAME_REGEX = /^(\d{4}-\d{2}-\d{2})-(.+)\.md$/;
const BASE = '../../site/content/blog';

/** @returns {import('./types').BlogData} */
export function get_blog_data(base = BASE) {
/** @type {import('./types').BlogData} */
const blog_posts = [];

for (const file of fs.readdirSync(base).reverse()) {
if (!BLOG_NAME_REGEX.test(file)) continue;

const { date, date_formatted, slug } = get_date_and_slug(file);
const { metadata, body } = extract_frontmatter(fs.readFileSync(`${base}/${file}`, 'utf-8'));

blog_posts.push({
date,
date_formatted,
content: body,
description: metadata.description,
draft: metadata.draft === 'true',
slug,
title: metadata.title,
author: {
name: metadata.author,
url: metadata.authorURL
}
});
}

return blog_posts;
}

/** @param {import('./types').BlogData} blog_data */
export function get_blog_list(blog_data) {
return blog_data.map(({ slug, date, title, description, draft }) => ({
slug,
date,
title,
description,
draft
}));
}

/** @param {string} filename */
function get_date_and_slug(filename) {
const match = BLOG_NAME_REGEX.exec(filename);
if (!match) throw new Error(`Invalid filename for blog: '${filename}'`);

const [, date, slug] = match;
const [y, m, d] = date.split('-');
const date_formatted = `${months[+m - 1]} ${+d} ${y}`;

return { date, date_formatted, slug };
}

const months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
141 changes: 81 additions & 60 deletions sites/svelte.dev/src/lib/server/blog/index.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,96 @@
import fs from 'fs';
import { extract_frontmatter } from '../markdown';
import { transform } from './marked';

const base = '../../site/content/blog';
// @ts-check
import { createShikiHighlighter } from 'shiki-twoslash';
import { SHIKI_LANGUAGE_MAP, escape, transform } from '../markdown';

/**
* @returns {import('./types').BlogPostSummary[]}
* @param {import('./types').BlogData} blog_data
* @param {string} slug
*/
export function get_index() {
return fs
.readdirSync(base)
.reverse()
.map((file) => {
if (!file.endsWith('.md')) return;
export async function get_processed_blog_post(blog_data, slug) {
const post = blog_data.find((post) => post.slug === slug);

const { date, slug } = get_date_and_slug(file);
if (!post) return null;

const content = fs.readFileSync(`${base}/${file}`, 'utf-8');
const { metadata } = extract_frontmatter(content);
const highlighter = await createShikiHighlighter({ theme: 'css-variables' });

return {
slug,
date,
title: metadata.title,
description: metadata.description,
draft: !!metadata.draft
};
});
}
return {
...post,
content: transform(post.content, {
/**
* @param {string} html
*/
heading(html) {
const title = html
.replace(/<\/?code>/g, '')
.replace(/&quot;/g, '"')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>');

/**
* @param {string} slug
* @returns {import('./types').BlogPost}
*/
export function get_post(slug) {
for (const file of fs.readdirSync(`${base}`)) {
if (!file.endsWith('.md')) continue;
if (file.slice(11, -3) !== slug) continue;
return title;
},
code: (source, language) => {
let html = '';

const { date, date_formatted } = get_date_and_slug(file);
source = source
.replace(/^([\-\+])?((?: )+)/gm, (match, prefix = '', spaces) => {
if (prefix && language !== 'diff') return match;

const content = fs.readFileSync(`${base}/${file}`, 'utf-8');
const { metadata, body } = extract_frontmatter(content);
// for no good reason at all, marked replaces tabs with spaces
let tabs = '';
for (let i = 0; i < spaces.length; i += 4) {
tabs += ' ';
}
return prefix + tabs;
})
.replace(/\*\\\//g, '*/');

return {
date,
date_formatted,
title: metadata.title,
description: metadata.description,
author: {
name: metadata.author,
url: metadata.authorURL
},
draft: !!metadata.draft,
content: transform(body)
};
}
}
if (language === 'diff') {
const lines = source.split('\n').map((content) => {
let type = null;
if (/^[\+\-]/.test(content)) {
type = content[0] === '+' ? 'inserted' : 'deleted';
content = content.slice(1);
}

/** @param {string} filename */
function get_date_and_slug(filename) {
const match = /^(\d{4}-\d{2}-\d{2})-(.+)\.md$/.exec(filename);
if (!match) throw new Error(`Invalid filename for blog: '${filename}'`);
return {
type,
content: escape(content)
};
});

const [, date, slug] = match;
const [y, m, d] = date.split('-');
const date_formatted = `${months[+m - 1]} ${+d} ${y}`;
html = `<pre class="language-diff"><code>${lines
.map((line) => {
if (line.type) return `<span class="${line.type}">${line.content}\n</span>`;
return line.content + '\n';
})
.join('')}</code></pre>`;
} else {
html = highlighter.codeToHtml(source, { lang: SHIKI_LANGUAGE_MAP[language] });

return { date, date_formatted, slug };
}
html = html
.replace(
/^(\s+)<span class="token comment">([\s\S]+?)<\/span>\n/gm,
(match, intro_whitespace, content) => {
// we use some CSS trickery to make comments break onto multiple lines while preserving indentation
const lines = (intro_whitespace + content).split('\n');
return lines
.map((line) => {
const match = /^(\s*)(.*)/.exec(line);
const indent = (match[1] ?? '').replace(/\t/g, ' ').length;

const months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
return `<span class="token comment wrapped" style="--indent: ${indent}ch">${
line ?? ''
}</span>`;
})
.join('');
}
)
.replace(/\/\*…\*\//g, '…');
}

function format_date(date) {}
return html;
},
codespan: (text) => '<code>' + text + '</code>'
})
};
}
Loading