Compare commits

...

10 Commits

Author SHA1 Message Date
1146f3b180 Add weight conversion to unit conversion tool. 2024-06-30 09:22:44 +08:00
5131b9396b Fix UI problem. 2024-06-30 09:22:44 +08:00
a8f0a86e07 Join lines broken by newlines to a long line.
Join paragraph lines that are broken by newlines from a long paragraph to a
long line. If the current line is a part of a block area, like pre, code,
blockquote, skip it.
2024-06-30 09:13:57 +08:00
3ed03f0496 Hide HTML h tag of table of content. 2024-06-30 09:13:56 +08:00
05c1b0d29b Add remark-toc plugin.
Add plugin for generating table of content automatically for markdown files.
2024-06-30 09:12:43 +08:00
2f54cf304a Fix layout probelm in using different fonts. 2024-06-30 09:12:41 +08:00
109357e8e2 Convert vue file from ts to js. 2024-06-30 09:12:41 +08:00
8563930e68 Disable 'markdown.smartypants' option.
Because it renders right and left quotes wrong.
2024-06-30 09:11:08 +08:00
8d07d60566 Remove deleted article files.
Delete non-existing files in the article dir from the target dir when rsync
transfers article files.
2024-06-30 09:05:48 +08:00
4cdce770d8 Add article definition to suppress the '[ERROR] The build was canceled.' log. 2024-06-30 09:05:23 +08:00
17 changed files with 413 additions and 88 deletions

5
.gitignore vendored
View File

@ -23,5 +23,6 @@ pnpm-debug.log*
# jetbrains setting folder
.idea/
# test articles
src/content/
# ignore test articles except for article definitions
src/content/*
!src/content/config.ts

View File

@ -1,10 +1,12 @@
import { defineConfig } from 'astro/config';
import sitemap from "@astrojs/sitemap";
import vue from "@astrojs/vue";
import remarkToc from 'remark-toc';
// https://astro.build/config
export default defineConfig({
markdown: {
smartypants: false,
syntaxHighlight: 'shiki',
shikiConfig: {
// Choose from Shiki's built-in themes (or add your own)
@ -25,7 +27,10 @@ export default defineConfig({
// Add custom transformers: https://shiki.style/guide/transformers
// Find common transformers: https://shiki.style/packages/transformers
transformers: []
}
},
remarkPlugins: [
[remarkToc, { heading: "(table[ -]of[ -])?contents?|toc|目录" }]
],
},
site: 'https://lishouzhong.com',
integrations: [

37
package-lock.json generated
View File

@ -14,6 +14,7 @@
"astro": "^4.9.2",
"bignumber.js": "^9.1.2",
"pinyin-pro": "^3.22.0",
"remark-toc": "^9.0.0",
"typescript": "^5.4.5",
"vue": "^3.4.29"
}
@ -1903,6 +1904,11 @@
"@types/node": "*"
}
},
"node_modules/@types/ungap__structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/@types/ungap__structured-clone/-/ungap__structured-clone-1.2.0.tgz",
"integrity": "sha512-ZoaihZNLeZSxESbk9PUAPZOlSpcKx81I1+4emtULDVmBLkYutTcMlCj2K9VNlf9EWODxdO6gkAqEaLorXwZQVA=="
},
"node_modules/@types/unist": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/unist/-/unist-3.0.2.tgz",
@ -4357,6 +4363,24 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-toc": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/mdast-util-toc/-/mdast-util-toc-7.1.0.tgz",
"integrity": "sha512-2TVKotOQzqdY7THOdn2gGzS9d1Sdd66bvxUyw3aNpWfcPXCLYSJCCgfPy30sEtuzkDraJgqF35dzgmz6xlvH/w==",
"dependencies": {
"@types/mdast": "^4.0.0",
"@types/ungap__structured-clone": "^1.0.0",
"@ungap/structured-clone": "^1.0.0",
"github-slugger": "^2.0.0",
"mdast-util-to-string": "^4.0.0",
"unist-util-is": "^6.0.0",
"unist-util-visit": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
@ -5575,6 +5599,19 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-toc": {
"version": "9.0.0",
"resolved": "https://registry.npmmirror.com/remark-toc/-/remark-toc-9.0.0.tgz",
"integrity": "sha512-KJ9txbo33GjDAV1baHFze7ij4G8c7SGYoY8Kzsm2gzFpbhL/bSoVpMMzGa3vrNDSWASNd/3ppAqL7cP2zD6JIA==",
"dependencies": {
"@types/mdast": "^4.0.0",
"mdast-util-toc": "^7.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/request-light": {
"version": "0.7.0",
"resolved": "https://registry.npmmirror.com/request-light/-/request-light-0.7.0.tgz",

View File

@ -16,6 +16,7 @@
"astro": "^4.9.2",
"bignumber.js": "^9.1.2",
"pinyin-pro": "^3.22.0",
"remark-toc": "^9.0.0",
"typescript": "^5.4.5",
"vue": "^3.4.29"
}

View File

@ -9,7 +9,9 @@ original_article_home="/home/ld/Documents/ld_article"
original_article_destination="/opt/ld-site/src/content"
ld_site_dist_target="/opt/nginx_targets/ld_site_dist"
rsync -a "${original_article_home}/" "${original_article_destination}/"
rsync -a --delete-after -f"P config.ts" \
"${original_article_home}/" \
"${original_article_destination}/"
cd "${script_path}/../"
npm run build
@ -21,4 +23,4 @@ fi
mv ${ld_site_dist_target} "${ld_site_dist_target}-old"
mv dist ${ld_site_dist_target}
rm -rf "${ld_site_dist_target}-old" ${original_article_destination}
rm -rf "${ld_site_dist_target}-old"

View File

@ -0,0 +1,37 @@
---
// get rendered ArticleBodyContent HTML
const html = await Astro.slots.render("default");
// If some lines are not started with ASCII character,
// join them to their previous line.
// This is important.
// Because I add one newline character to wrap Chinese.
const arr = html.split("\n");
let articleHTMLFinal = arr[0];
// Whether the current line belongs to the area where
// the line break should be kept.
let remainIntactArea = false;
for (let i = 1; i < arr.length; i++) {
if (arr[i].match(/^(<pre|<code|<blockquote|<table)/) !== null) {
remainIntactArea = true;
} else {
remainIntactArea = false;
}
if (
// If the first character is not ascii character,
// or the final character of previous line is not character.
// AND
// Current line should not belong to area that remains intact.
(arr[i].charAt(0).match(/[ -~]/) === null ||
arr[i - 1].charAt(arr[i - 1].length - 1).match(/[ -~]/) === null) &&
!remainIntactArea
) {
articleHTMLFinal += arr[i];
} else {
articleHTMLFinal += "\n";
articleHTMLFinal += arr[i];
}
}
---
<Fragment set:html={articleHTMLFinal} />

View File

@ -45,10 +45,14 @@ const articlePrettyName = article!.id.split("/").pop()!.replace(".md", "");
flex-wrap: wrap;
}
/* reduce indent of TOC list */
:global(.article-title + ul) {
:global(.article-title ~ ul:nth-of-type(1)) {
margin: 1em 0 1em 0;
padding: 0 0 0 20px;
}
/* hide TOC headint */
:global(.article-title ~ h2:nth-of-type(1)) {
display: none;
}
/* font for all code */
:global(.article code) {
font-family: "Consolas", "Tahoma", sans-serif;

View File

@ -0,0 +1,18 @@
---
import type { CollectionKey } from "astro:content";
import ArticleBody from "./ArticleBody.astro";
import ArticleBodyContent from "./ArticleBodyContent.astro";
interface Props {
articleSlug: string;
collectionName: CollectionKey;
}
const { articleSlug, collectionName } = Astro.props;
---
<ArticleBody>
<ArticleBodyContent
collectionName={collectionName}
articleSlug={articleSlug}
/>
</ArticleBody>

View File

@ -1,53 +1,86 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
<script setup>
import { computed, ref } from 'vue';
import BigNumber from "bignumber.js";
const unitToByte: { [name: string]: number } = {
"unit-k-byte": 1000,
"unit-m-byte": 1000 * 1000,
"unit-g-byte": 1000 * 1000 * 1000,
"unit-t-byte": 1000 * 1000 * 1000 * 1000,
"unit-ki-byte": 1024,
"unit-mi-byte": 1024 * 1024,
"unit-gi-byte": 1024 * 1024 * 1024,
"unit-ti-byte": 1024 * 1024 * 1024 * 1024,
"unit-byte": 1,
"unit-bit": 1 / 8,
"unit-k-bit": 1000 / 8,
"unit-m-bit": 1000000 / 8,
"unit-g-bit": 1000000000 / 8,
"unit-t-bit": 1000000000000 / 8,
}
/**
* @typedef {string} UnitNameStr
*/
let variable: { [name: keyof typeof unitToByte]: string } = {
"unit-k-byte": '',
"unit-m-byte": '',
"unit-g-byte": '',
"unit-t-byte": '',
"unit-ki-byte": '',
"unit-mi-byte": '',
"unit-gi-byte": '',
"unit-ti-byte": '',
"unit-byte": '',
"unit-bit": '',
"unit-k-bit": '',
"unit-m-bit": '',
"unit-g-bit": '',
"unit-t-bit": '',
}
/**
* @enum {UnitNameStr}
*/
const UnitName = Object.freeze({
KBYTE: "unit-k-byte",
MBYTE: "unit-m-byte",
GBYTE: "unit-g-byte",
TBYTE: "unit-t-byte",
KIBYTE: "unit-ki-byte",
MIBYTE: "unit-mi-byte",
GIBYTE: "unit-gi-byte",
TIBYTE: "unit-ti-byte",
BYTE: "unit-byte",
BIT: "unit-bit",
KBIT: "unit-k-bit",
MBIT: "unit-m-bit",
GBIT: "unit-g-bit",
TBIT: "unit-t-bit",
})
const size = ref(variable);
/**
* @enum {number}
*/
const UnitNameToSize = Object.freeze({
[UnitName.KBYTE]: 1000,
[UnitName.MBYTE]: 1000 * 1000,
[UnitName.GBYTE]: 1000 * 1000 * 1000,
[UnitName.TBYTE]: 1000 * 1000 * 1000 * 1000,
[UnitName.KIBYTE]: 1024,
[UnitName.MIBYTE]: 1024 * 1024,
[UnitName.GIBYTE]: 1024 * 1024 * 1024,
[UnitName.TIBYTE]: 1024 * 1024 * 1024 * 1024,
[UnitName.BYTE]: 1,
[UnitName.BIT]: 1 / 8,
[UnitName.KBIT]: 1000 / 8,
[UnitName.MBIT]: 1000000 / 8,
[UnitName.GBIT]: 1000000000 / 8,
[UnitName.TBIT]: 1000000000000 / 8,
});
function sizeChanged(unitName: keyof typeof unitToByte):void {
let result: { [name in keyof typeof unitToByte]: string } = Object();
const size = ref({
[UnitName.KBYTE]: '',
[UnitName.MBYTE]: '',
[UnitName.GBYTE]: '',
[UnitName.TBYTE]: '',
[UnitName.KIBYTE]: '',
[UnitName.MIBYTE]: '',
[UnitName.GIBYTE]: '',
[UnitName.TIBYTE]: '',
[UnitName.BYTE]: '',
[UnitName.BIT]: '',
[UnitName.KBIT]: '',
[UnitName.MBIT]: '',
[UnitName.GBIT]: '',
[UnitName.TBIT]: '',
});
/**
* Change ref variable when user inputs some characters.
* @param {UnitNameStr} unitName
* @returns {void}
*/
function sizeChanged(unitName) {
/**
* @type {object.<UnitNameStr, string>}
*/
let result = {};
// assign 0 to current input if nothing is passed
if (size.value[unitName].length === 0) result[unitName] = '0';
let inputedBytes: BigNumber = new BigNumber(unitToByte[unitName]).multipliedBy(size.value[unitName]);
for (const key in unitToByte) {
result[key] = inputedBytes.div(unitToByte[key]).toString();
let inputedBytes = new BigNumber(UnitNameToSize[unitName]).multipliedBy(size.value[unitName]);
for (const key in UnitNameToSize) {
result[key] = inputedBytes.div(UnitNameToSize[key]).toString();
}
result[unitName] = size.value[unitName];
for (const key in unitToByte) {
for (const key in UnitNameToSize) {
if (result[key] !== 'NaN') {
size.value[key] = result[key];
} else if (result[key] === 'NaN') {
@ -57,7 +90,7 @@ function sizeChanged(unitName: keyof typeof unitToByte):void {
}
const isMultipleOf4KiB = computed(() => {
let userInput: BigNumber = new BigNumber(size.value["unit-ki-byte"])
let userInput = new BigNumber(size.value[UnitName.KIBYTE]);
if (userInput.toNumber() === 0) return false;
return userInput.mod(4).toNumber() === 0 ? true : false;
})
@ -66,82 +99,84 @@ const isMultipleOf4KiB = computed(() => {
<template>
<h1>数据单位换算</h1>
<div class="unit-conversion-computation-area 1000-in-byte">
<p>1000 进制并以 Byte : </p>
<p>1000 进制并以 Byte :</p>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-k-byte" type="text" v-model="size['unit-k-byte']"
@input="sizeChanged('unit-k-byte')">
<input class="size-text" :id="UnitName.KBYTE" type="text" v-model="size[UnitName.KBYTE]"
@input="sizeChanged(UnitName.KBYTE)">
<span class="unit-name">KB</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-m-byte" type="text" v-model="size['unit-m-byte']"
@input="sizeChanged('unit-m-byte')">
<input class="size-text" :id="UnitName.MBYTE" type="text" v-model="size[UnitName.MBYTE]"
@input="sizeChanged(UnitName.MBYTE)">
<span class="unit-name">MB</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-g-byte" type="text" v-model="size['unit-g-byte']"
@input="sizeChanged('unit-g-byte')">
<input class="size-text" :id="UnitName.GBYTE" type="text" v-model="size[UnitName.GBYTE]"
@input="sizeChanged(UnitName.GBYTE)">
<span class="unit-name">GB</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-t-byte" type="text" v-model="size['unit-t-byte']"
@input="sizeChanged('unit-t-byte')">
<input class="size-text" :id="UnitName.TBYTE" type="text" v-model="size[UnitName.TBYTE]"
@input="sizeChanged(UnitName.TBYTE)">
<span class="unit-name">TB</span>
</div>
</div>
<div class="unit-conversion-computation-area 1024-in-byte">
<p>1024 进制并以 Byte </p>
<p>1024 进制并以 Byte :</p>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-ki-byte" type="text" v-model="size['unit-ki-byte']"
@input="sizeChanged('unit-ki-byte')">
<input class="size-text" :id="UnitName.KIBYTE" type="text" v-model="size[UnitName.KIBYTE]"
@input="sizeChanged(UnitName.KIBYTE)">
<span class="unit-name">KiB</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-mi-byte" type="text" v-model="size['unit-mi-byte']"
@input="sizeChanged('unit-mi-byte')">
<input class="size-text" :id="UnitName.MIBYTE" type="text" v-model="size[UnitName.MIBYTE]"
@input="sizeChanged(UnitName.MIBYTE)">
<span class="unit-name">MiB</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-gi-byte" type="text" v-model="size['unit-gi-byte']"
@input="sizeChanged('unit-gi-byte')">
<input class="size-text" :id="UnitName.GIBYTE" type="text" v-model="size[UnitName.GIBYTE]"
@input="sizeChanged(UnitName.GIBYTE)">
<span class="unit-name">GiB</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-ti-byte" type="text" v-model="size['unit-ti-byte']"
@input="sizeChanged('unit-ti-byte')">
<input class="size-text" :id="UnitName.TIBYTE" type="text" v-model="size[UnitName.TIBYTE]"
@input="sizeChanged(UnitName.TIBYTE)">
<span class="unit-name">TiB</span>
</div>
</div>
<div class="unit-conversion-computation-area byte-bit">
<p> Byte (B) / bit (b) :</p>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-byte" type="text" v-model="size['unit-byte']" @input="sizeChanged('unit-byte')">
<input class="size-text" :id="UnitName.BYTE" type="text" v-model="size[UnitName.BYTE]"
@input="sizeChanged(UnitName.BYTE)">
<span class="unit-name">B</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-bit" type="text" v-model="size['unit-bit']" @input="sizeChanged('unit-bit')">
<input class="size-text" :id="UnitName.BIT" type="text" v-model="size[UnitName.BIT]"
@input="sizeChanged(UnitName.BIT)">
<span class="unit-name">b</span>
</div>
</div>
<div class="unit-conversion-computation-area 1000-in-bit">
<p>1000 进制并以 bit :</p>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-k-bit" type="text" v-model="size['unit-k-bit']"
@input="sizeChanged('unit-k-bit')">
<input class="size-text" :id="UnitName.KBIT" type="text" v-model="size[UnitName.KBIT]"
@input="sizeChanged(UnitName.KBIT)">
<span class="unit-name">Kb</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-m-bit" type="text" v-model="size['unit-m-bit']"
@input="sizeChanged('unit-m-bit')">
<input class="size-text" :id="UnitName.MBIT" type="text" v-model="size[UnitName.MBIT]"
@input="sizeChanged(UnitName.MBIT)">
<span class="unit-name">Mb</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-g-bit" type="text" v-model="size['unit-g-bit']"
@input="sizeChanged('unit-g-bit')">
<input class="size-text" :id="UnitName.GBIT" type="text" v-model="size[UnitName.GBIT]"
@input="sizeChanged(UnitName.GBIT)">
<span class="unit-name">Gb</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" id="unit-t-bit" type="text" v-model="size['unit-t-bit']"
@input="sizeChanged('unit-t-bit')">
<input class="size-text" :id="UnitName.TBIT" type="text" v-model="size[UnitName.TBIT]"
@input="sizeChanged(UnitName.TBIT)">
<span class="unit-name">Tb</span>
</div>
</div>
@ -165,7 +200,7 @@ p,
.size-text {
margin: 0 6px 0 0;
width: 130px
width: 125px
}
@media screen and (max-width: 395px) {
@ -174,7 +209,7 @@ p,
}
.size-text {
width: 90px;
width: 85px;
}
}

View File

@ -1,5 +1,8 @@
---
import DataUnitConversion from "./DataUnitConversion.vue";
import WeightConversion from "./WeightConversion.vue";
---
<DataUnitConversion client:load />
<WeightConversion client:load />

View File

@ -0,0 +1,147 @@
<script setup>
import { computed, ref } from 'vue';
import BigNumber from "bignumber.js";
/**
* @typedef {string} UnitNameStr
*/
/**
* @enum {UnitNameStr}
*/
const twToMetricUnitName = Object.freeze({
JIN: "jin",
LIANG: "liang",
QIAN: "qian",
FEN: "fen",
GRAM: "gram",
KILOGRAM: "kilogram"
})
/**
* @enum {number}
*/
const twToMetricUnitNameToWeight = Object.freeze({
[twToMetricUnitName.JIN]: 600,
[twToMetricUnitName.LIANG]: 600 / 16,
[twToMetricUnitName.QIAN]: 600 / 16 / 10,
[twToMetricUnitName.FEN]: 600 / 16 / 10 / 10,
[twToMetricUnitName.GRAM]: 1,
[twToMetricUnitName.KILOGRAM]: 1 * 1000,
})
const weight = ref({
[twToMetricUnitName.JIN]: '',
[twToMetricUnitName.LIANG]: '',
[twToMetricUnitName.QIAN]: '',
[twToMetricUnitName.FEN]: '',
[twToMetricUnitName.GRAM]: '',
[twToMetricUnitName.KILOGRAM]: '',
});
/**
* Change ref variable when user inputs some characters.
* @param {UnitNameStr} unitName
* @returns {void}
*/
function weightChanged(unitName) {
/**
* @type {object.<UnitNameStr, string>}
*/
let result = {};
// assign 0 to current input if nothing is passed
if (weight.value[unitName].length === 0) result[unitName] = '0';
let inputedGram = new BigNumber(twToMetricUnitNameToWeight[unitName]).multipliedBy(weight.value[unitName]);
for (const key in twToMetricUnitNameToWeight) {
result[key] = inputedGram.div(twToMetricUnitNameToWeight[key]).toString();
}
result[unitName] = weight.value[unitName];
for (const key in twToMetricUnitNameToWeight) {
if (result[key] !== 'NaN') {
weight.value[key] = result[key];
} else if (result[key] === 'NaN') {
weight.value[key] = '';
}
}
}
</script>
<template>
<h1>重量换算</h1>
<div class="unit-conversion-computation-area metric">
<p>公制重量:</p>
<div class="unit-conversion-computation-node">
<input class="size-text" :id="twToMetricUnitName.KILOGRAM" type="text"
v-model="weight[twToMetricUnitName.KILOGRAM]" @input="weightChanged(twToMetricUnitName.KILOGRAM)">
<span class="unit-name">千克</span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" :id="twToMetricUnitName.GRAM" type="text" v-model="weight[twToMetricUnitName.GRAM]"
@input="weightChanged(twToMetricUnitName.GRAM)">
<span class="unit-name"></span>
</div>
</div>
<div class="unit-conversion-computation-area tw">
<p>台湾制重量:</p>
<div class="unit-conversion-computation-node">
<input class="size-text" :id="twToMetricUnitName.JIN" type="text" v-model="weight[twToMetricUnitName.JIN]"
@input="weightChanged(twToMetricUnitName.JIN)">
<span class="unit-name"></span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" :id="twToMetricUnitName.LIANG" type="text" v-model="weight[twToMetricUnitName.LIANG]"
@input="weightChanged(twToMetricUnitName.LIANG)">
<span class="unit-name"></span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" :id="twToMetricUnitName.QIAN" type="text" v-model="weight[twToMetricUnitName.QIAN]"
@input="weightChanged(twToMetricUnitName.QIAN)">
<span class="unit-name"></span>
</div>
<div class="unit-conversion-computation-node">
<input class="size-text" :id="twToMetricUnitName.FEN" type="text" v-model="weight[twToMetricUnitName.FEN]"
@input="weightChanged(twToMetricUnitName.FEN)">
<span class="unit-name"></span>
</div>
</div>
</template>
<style>
h1,
p,
.unit-conversion-computation-node {
margin: 0.5em 0;
}
.unit-conversion-computation-node {
float: left;
width: 170px;
margin: 0 8px 0 0;
}
.size-text {
margin: 0 6px 0 0;
width: 115px
}
@media screen and (max-width: 395px) {
.unit-conversion-computation-node {
width: 130px;
}
.size-text {
width: 85px;
}
}
.unit-conversion-computation-area::after {
content: '';
display: block;
clear: both;
}
.unit-conversion-computation-result {
margin: 0.5em 0 0.5em 0;
height: 1em;
}
</style>

35
src/content/config.ts Normal file
View File

@ -0,0 +1,35 @@
import { z, defineCollection } from 'astro:content';
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
category: z.string(),
lastUpdate: z.string()
}),
});
const noteCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
category: z.string(),
lastUpdate: z.string()
}),
});
const translationCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
category: z.string(),
lastUpdate: z.string()
}),
});
export const collections = {
'blog': blogCollection,
'note': noteCollection,
'translation': translationCollection,
};

View File

@ -2,11 +2,11 @@
import DefaultLayout from "../layouts/DefaultLayout.astro";
import Nav from "../components/Nav.astro";
import Footer from "../components/Footer.astro";
import ArticleBody from "../components/article/ArticleBody.astro";
import ArticleBodyWrapper from "../components/article/article_body/ArticleBodyWrapper.astro";
---
<DefaultLayout title="404">
<Nav />
<ArticleBody collectionName="site" articleSlug="404" />
<ArticleBodyWrapper collectionName="site" articleSlug="404" />
<Footer />
</DefaultLayout>

View File

@ -7,7 +7,7 @@ import type {
} from "astro:content";
import Footer from "../../../components/Footer.astro";
import Nav from "../../../components/Nav.astro";
import ArticleBody from "../../../components/article/ArticleBody.astro";
import ArticleBodyWrapper from "../../../components/article/article_body/ArticleBodyWrapper.astro";
import DefaultLayout from "../../../layouts/DefaultLayout.astro";
export async function getStaticPaths() {
@ -29,6 +29,6 @@ const articlePrettyName:string = entry.id.split("/").pop()!.replace(".md", "");
<DefaultLayout title=`${articlePrettyName} - 李守中`>
<Nav />
<ArticleBody collectionName="blog" articleSlug={entry.slug} />
<ArticleBodyWrapper collectionName="blog" articleSlug={entry.slug} />
<Footer />
</DefaultLayout>

View File

@ -7,7 +7,7 @@ import type {
} from "astro:content";
import Footer from "../../../components/Footer.astro";
import Nav from "../../../components/Nav.astro";
import ArticleBody from "../../../components/article/ArticleBody.astro";
import ArticleBodyWrapper from "../../../components/article/article_body/ArticleBodyWrapper.astro";
import DefaultLayout from "../../../layouts/DefaultLayout.astro";
export async function getStaticPaths() {
@ -29,6 +29,6 @@ const articlePrettyName:string = entry.id.split("/").pop()!.replace(".md", "");
<DefaultLayout title=`${articlePrettyName} - 李守中`>
<Nav />
<ArticleBody collectionName="note" articleSlug={entry.slug} />
<ArticleBodyWrapper collectionName="note" articleSlug={entry.slug} />
<Footer />
</DefaultLayout>

View File

@ -7,7 +7,7 @@ import type {
} from "astro:content";
import Footer from "../../../components/Footer.astro";
import Nav from "../../../components/Nav.astro";
import ArticleBody from "../../../components/article/ArticleBody.astro";
import ArticleBodyWrapper from "../../../components/article/article_body/ArticleBodyWrapper.astro";
import DefaultLayout from "../../../layouts/DefaultLayout.astro";
export async function getStaticPaths() {
@ -29,6 +29,6 @@ const articlePrettyName:string = entry.id.split("/").pop()!.replace(".md", "");
<DefaultLayout title=`${articlePrettyName} - 李守中`>
<Nav />
<ArticleBody collectionName="translation" articleSlug={entry.slug} />
<ArticleBodyWrapper collectionName="translation" articleSlug={entry.slug} />
<Footer />
</DefaultLayout>

View File

@ -2,11 +2,11 @@
import DefaultLayout from "../layouts/DefaultLayout.astro";
import Nav from "../components/Nav.astro";
import Footer from "../components/Footer.astro";
import ArticleBody from "../components/article/ArticleBody.astro";
import ArticleBodyWrapper from "../components/article/article_body/ArticleBodyWrapper.astro";
---
<DefaultLayout title="李守中">
<Nav />
<ArticleBody collectionName="site" articleSlug="关于本站" />
<ArticleBodyWrapper collectionName="site" articleSlug="关于本站" />
<Footer />
</DefaultLayout>