Hello World! 此博客的第一篇文章

Hello World! 此博客的第一篇文章

说明

这是我的第一篇博客,实际在去年我就有搭建博客的想法,不过那时对这些技术不了解,所以就什么都没做。
这段时间学了一部分 JavaSE,想要把学的过程中那些事分享出来,所以又重新来搭建博客。

这不是一个博客搭建教程,我也是看着别人的教程一步步摸出来的。这个是视频教程这个是Butterfly的教程

原本使用 Github Pages 来创建博客,但 github.io 无法访问,所以采用了 Gitee Pages 来创建博客。

中间还遇到了不少麻烦,不过好在都一一解决了,花了 3 天完成了这个博客的部署和使用上的学习。

25 年 3 月 9 日更新

2022 年 5 月 29 日,因某些原因,我开始开发自己的博客框架 Ezal…三年过去,缝缝补补,Ezal 仍旧未能完工…

25 年 11 月 20 日更新

马上要年底了,所以决定来重构整个博客框架,ezal-markdown 目前也基本可用,虽然还有一些小 bug,另外把代码高亮库替换成 shiki,这样一来就和 vscode 中的高亮效果非常相似了。
重构框架还有一个原因就是 3 月份写的框架在预览模式下速度很慢,目前新的用起来感觉尚好,不至于一个主页要等几十秒才加载出来。


CommonMark Spec & GFM 语法

标题

三级标题

四级标题
五级标题

为了优化 SEO 以及写作体验,文章的标题会渲染为 <h1>,而 markdown 中编写的标题会降低第一个等级,即原本的 <h1> 会渲染为 <h2>,以此类推,五级标题和六级标题都会渲染为六级标题。

文本

The quick brown fox jumps over a lazy dog.
一只快速棕色狐狸跳过了一只懒惰的狗。

引用块

从前有座山,山里有座庙,庙里有个老和尚在讲故事,讲的是什么呢?讲的是:

从前有座山,山里有座庙,庙里有个老和尚在讲故事,讲的是什么呢?讲的是:

Uncaught RangeError: Maximum call stack size exceeded

有序列表

  1. 读取配置文件
  2. 扫描资源
  3. 构建主题资源
  4. 构建用户资源
  5. 构建文章
  6. 构建页面
  7. 构建虚拟资源
  8. 构建虚拟页面

无序列表

单行代码

预览:ezal serve --verbose
构建:ezal build --clean

链接

欢迎光临 Jonny's Blog

引用链接

图像

cover
cover

favicon与一般的渲染不同,支持行内与块级两种图像!
并且可以自动生成 webp 与 avif 两种格式的图像,提升加载速度!
另外,通过将图片尺寸、主色调写入 <img>,还可以避免布局偏移,以及显示色块作为占位符!

表格

默认对齐左对齐居中对齐右对齐
文本左对齐居左居中右对齐
数字123456789
加粗斜体删除线
空单元格
长文本测试:Lorem ipsum dolor sit amet期朝片右服没活架高染相策哪报在往杂。中间对齐的混合内容右侧金额数字
带链接的单元格代码块图标

支持:

代码块

TypeScriptcodeblock.ts
import type { markdown } from 'ezal';
import hljs from 'highlight.js';
import prismjs from 'prismjs';
import loadLanguages from 'prismjs/components/index';
import { renderLine } from '../renderer';

interface Matched extends markdown.Matched {
	code: string;
	lang?: string;
	info?: string;
}

const PATTERN_START = /(?:(?<=\n)|^)(~~~|```)/;

const MAP: Record<string, RegExp> = {
	'~': /\n~{3,}(?:(?=\n)|$)/,
	'`': /\n`{3,}(?:(?=\n)|$)/,
};

// 代码块
export const codeblock: markdown.IExtension<Matched> = {
	name: 'codeblock',
	level: 'block',
	priority: 0,
	start(src) {
		return src.match(PATTERN_START);
	},
	match(src) {
		const start = src.match(PATTERN_START)!;
		let endIndex = src.length;
		const end = src.match(MAP[src[0]]);
		if (end) {
			endIndex = end.index!;
			src = src.slice(0, endIndex + end[0].length);
		}
		let startIndex = src.indexOf('\n');
		if (startIndex === -1) startIndex = src.length;

		let info = src.slice(start[0].length, startIndex);
		let lang: string | undefined = undefined;
		if (info) {
			info = info.trim();
			let index = info.indexOf(' ');
			if (index === -1) index = info.length;
			lang = info.slice(0, index);
			info = info.slice(index).trim();
		}

		const code = src.slice(startIndex + 1, endIndex);

		return {
			raw: src,
			text: code,
			code,
			lang,
			info,
		};
	},
	async render(matched, variables, options) {
		variables.codeBlock = true;
		let html = '<figure class="code">';
		if (!matched.lang) {
			matched.lang = hljs.highlightAuto(matched.code).language;
		}
		if (matched.lang) {
			html += `<figcaption><code>${variables.counter.count(matched.lang)}</code>`;
			if (matched.info) {
				html += (await renderLine(matched.info, options, variables)).content;
			}
			html += '</figcaption>';
		}

		if (!matched.lang) matched.lang = 'plaintext';

		loadLanguages([matched.lang]);
		const result = prismjs.highlight(
			matched.code,
			prismjs.languages[matched.lang],
			matched.lang,
		);

		html += `<pre class="language-${matched.lang}"><code>${result}</code></pre></figure>`;

		variables.counter.count(matched.code);

		return html;
	},
};

Shiki 特性测试:

TypeScript
console.log('Hello');
console.log('Ciao');
console.log('你好');
console.error(new Error());
console.warn('Warn!');

任务列表

附加语法

数学公式

行内数学公式

块级数学公式:

脚注

这是一个基本脚注引用1的示例。也可以多次引用同一个脚注1,或是引用不同脚注2

包含复杂格式的脚注示例special

如果将鼠标光标移动到脚注引用上,还可以在不跳转的情况下预览!

1
基础脚注内容(可重复引用的通用说明)
2
独立脚注内容
special
复杂格式脚注:
此处支持块级语法,比如代码块。
现在,预览中的代码块同样支持一键复制!
JavaScript
console.log('Hello world!');
此外,还支持复杂的嵌套
嵌套测试
JavaScript
console.log('Hello world!');
JavaScript
console.log('Hello world!');

主题自定义语法

Tabs

第一个标签的内容。

第二个标签的内容。

Markdown
标签内容支持块级 *Markdown* 语法

Fold

展开查看详情

此处可以使用块级语法:

JavaScript
console.log('Hello world!');

Note

注意

应当了解的信息。

提示

提示信息。

警告

需要立即关注的重要信息。

危险

关于某些行动可能带来的风险或负面结果的建议。

Kbd

Press ctrl shift del to do something...