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

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

说明

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

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

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

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

25 年 3 月 9 日更新

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


Markdown 渲染器测试

Markdown 原生语法 & 常见扩展语法

标题

四级标题
五级标题
六级标题

Markdown 渲染器启用了针对 Bing 的 SEO 优化,文章中的标题会渲染为比实际低一级的标题,而 markdown 中的五级和六级标题都会被渲染为六级标题<h6>

装饰性文本

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

引用块

咕咕咕……
不知道写什么好。
那就随便写点东西来测试。
从前有座山,
山里有座庙,
庙里有个老和尚在讲故事,
讲的是什么呢?
讲的是:
从前有座山,
山里有座庙,
庙里有个老和尚在讲故事,
讲的是什么呢?
讲的是:
Uncaught RangeError: Maximum call stack size exceeded

有序列表

  1. 读取配置文件
  2. 读取文章
  3. 读取用户自定义页面
  4. 初始化 Markdown 渲染器
  5. 预处理文章
  6. 初始化主题
  7. 启动预览服务器

无序列表

单行代码

测试主题:pnpm dev
预览:pnpm serve
构建:pnpm build

链接

欢迎光临 Jonny's Blog

引用链接

引用链接源
https://jonnys.top

图像

cover
文章封面图

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

表格

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

支持:

代码块

tscodeblock.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;
	},
};

脚注

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

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

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

1
基础脚注内容(可重复引用的通用说明)
2
独立脚注内容
special
复杂格式脚注:
此处支持块级语法,比如代码块
js
console.log('Hello world!');

定义列表

术语 (Term)
定义描述内容(Definition)
暂不支持块级语法

任务列表

数学公式

行内数学公式

块级数学公式:

自定义 Tag 语法

Note

注意

应当了解的信息。

提示

提示信息

警告

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

危险

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

Kbd

ctrlshiftdel

Fold

展开查看详情

此处可以使用块级语法:

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