diff --git a/articles b/articles
new file mode 160000
index 0000000..3744bd7
--- /dev/null
+++ b/articles
@@ -0,0 +1 @@
+Subproject commit 3744bd78995594e5fdfcaeff32f426f1d41daffa
diff --git a/package-lock.json b/package-lock.json
index bee0623..262b8ea 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"globals": "^15.0.0",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
+ "shiki": "^1.16.2",
"svelte": "^5.0.0-next.1",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
@@ -494,6 +495,24 @@
"linux"
]
},
+ "node_modules/@shikijs/core": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.16.2.tgz",
+ "integrity": "sha512-XSVH5OZCvE4WLMgdoBqfPMYmGHGmCC3OgZhw0S7KcSi2XKZ+5oHGe71GFnTljgdOxvxx5WrRks6QoTLKrl1eAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^9.2.0",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.2.0.tgz",
+ "integrity": "sha512-5FinaOp6Vdh/dl4/yaOTh0ZeKch+rYS8DUb38V3GMKYVkdqzxw53lViRKUYkVILRiVQT7dcPC7VvAKOR73zVtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@sveltejs/adapter-auto": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.4.tgz",
@@ -620,6 +639,16 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"license": "MIT"
},
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -3259,6 +3288,18 @@
"node": ">=8"
}
},
+ "node_modules/shiki": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.16.2.tgz",
+ "integrity": "sha512-gSym0hZf5a1U0iDPsdoOAZbvoi+e0c6c3NKAi03FoSLTm7oG20tum29+gk0wzzivOasn3loxfGUPT+jZXIUbWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "1.16.2",
+ "@shikijs/vscode-textmate": "^9.2.0",
+ "@types/hast": "^3.0.4"
+ }
+ },
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
diff --git a/package.json b/package.json
index 332f2c6..99a33da 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"globals": "^15.0.0",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
+ "shiki": "^1.16.2",
"svelte": "^5.0.0-next.1",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
diff --git a/src/lib/blog.scss b/src/lib/blog.scss
index 4c6cfcc..95a98c9 100644
--- a/src/lib/blog.scss
+++ b/src/lib/blog.scss
@@ -1,30 +1,34 @@
.document {
--color-text: #ffffff;
- --color-concept: hsl(39, 100%, 25%, 0.5);
+ --color-concept: hsla(40, 100%, 90%, 0.5);
--color-concept-hsl: 39, 100%, 25%;
--color-outline: #ffffff40;
width: 100%;
- * {
- color: var(--color-text);
- }
+
+ color: var(--color-text);
+
h1 {
position: relative;
width: auto;
font-size: 2rem;
margin-bottom: 0.5rem;
}
+
hr {
padding: 0;
margin: 0;
border: none;
border-top: 1px solid var(--color-outline);
}
- > *:not(h1, hr) {
+
+ >*:not(h1, hr) {
margin-left: 2rem;
}
+
h2 {
font-size: 1.5rem;
position: relative;
+
&::before {
content: '#';
position: absolute;
@@ -34,30 +38,38 @@
color: rgb(131, 131, 131);
}
}
+
h3 {
font-size: 1.25rem;
}
+
h4 {
font-size: 1.05rem;
}
+
hr {
border: none;
border-top: 1px solid var(--color-outline);
}
+
img {
max-height: 300px;
}
+
a {
+ color: var(--color-text);
position: relative;
display: inline-block;
transform: translate(0, 0);
text-shadow: 0 0 1rem hsl(var(--color-concept-hsl));
transition: 0.2s ease-out;
font-weight: normal;
+
&:hover {
transform: translate(0, -0.1rem);
}
}
+
blockquote {
position: relative;
font-size: 1.1rem;
@@ -65,6 +77,7 @@
padding: 0;
padding-left: 1rem;
color: rgb(162, 162, 162);
+
&::before {
content: '“';
position: absolute;
@@ -74,6 +87,7 @@
color: rgb(131, 131, 131);
}
}
+
warn {
position: relative;
display: block;
@@ -81,9 +95,10 @@
background-image: linear-gradient(to right, var(--color-outline), transparent 75%);
background-origin: border-box;
box-shadow: inset 0 0 0 100vh var(--background-color);
- text-shadow: 0 0 1rem hsl(var(--color-concept-hsl),1);
+ text-shadow: 0 0 1rem hsl(var(--color-concept-hsl), 1);
border: 1px solid transparent;
border-radius: 0.5rem;
+
&::before {
content: 'note:warn';
position: relative;
@@ -95,19 +110,42 @@
text-shadow: 0 0 1rem red;
}
}
+
pre {
font-family: monospace;
+ position: relative;
+ display: block;
margin-top: 0.75rem;
margin-bottom: 0.75rem;
- white-space: pre-wrap;
- }
- code {
- display: inline-block;
- padding: 0.2rem;
- background: rgba(255, 255, 255, 0.25);
- border-radius: 0.2rem;
- font-family: monospace;
+ border: 2px solid #ffffff40;
+ border-radius: 0.5rem;
+ overflow-x: scroll;
+
+ &::-webkit-scrollbar {
+ border-radius: 10px;
+ height: 10px;
+ width: 8px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #999;
+ border-radius: 10px;
+ }
+
+ &::-webkit-scrollbar-track {
+ border-radius: 10px;
+ }
+
+ >code {
+ display: inline-block;
+ padding: 0.5rem;
+ border-radius: 0.6rem;
+ font-family: monospace;
+ box-sizing: border-box;
+ min-width: 100%;
+ }
}
+
details {
position: relative;
display: block;
@@ -115,7 +153,8 @@
transition: 0.2s ease-out;
transition-property: height;
padding-inline-start: 0.1rem;
- > summary {
+
+ >summary {
position: relative;
border-radius: 0.5rem;
list-style: '+ ' outside;
@@ -123,36 +162,43 @@
padding: 0.2rem;
background: linear-gradient(to right, rgba(255, 255, 255, 0.25), transparent 200px);
cursor: pointer;
+
&:hover {
text-shadow: 0 0 0.25rem rgb(255, 255, 255);
}
}
- > p {
+
+ >p {
margin-block-start: 0.5rem;
margin-block-end: 0.5rem;
margin-left: 1rem;
display: none;
}
+
&[open] {
- > summary {
+ >summary {
list-style: '- ' outside;
}
- > p {
+
+ >p {
animation: detailsIn 0.5s ease;
display: block;
}
}
}
+
@keyframes detailsIn {
0% {
opacity: 0;
transform: translateY(-10px);
}
+
100% {
opacity: 1;
transform: none;
}
}
+
table {
border-spacing: 0;
border: none;
@@ -160,22 +206,26 @@
border-radius: 10px;
overflow: hidden;
box-shadow: 0 0 0.5rem hsl(var(--color-concept-hsl), 0.5);
+
thead {
background-color: rgba(0, 0, 0, 0.1);
color: #fff;
}
+
tr {
&:nth-child(2n) {
background-color: #ffffff0d;
}
}
+
td,
th {
padding: 0.5em;
border-left: 1px solid var(--color-outline);
+
&:first-child {
border-left: none;
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/lib/kanagawa.json b/src/lib/kanagawa.json
new file mode 100644
index 0000000..8a3c6a2
--- /dev/null
+++ b/src/lib/kanagawa.json
@@ -0,0 +1,915 @@
+{
+ "name": "Kanagawa",
+ "type": "dark",
+ "semanticHighlighting": true,
+ "colors": {
+ "activityBar.background": "#2A2A37",
+ "activityBar.foreground": "#DCD7BA",
+ "activityBarBadge.background": "#658594",
+ "activityBarBadge.foreground": "#DCD7BA",
+ "badge.background": "#2A2A37",
+ "button.background": "#2A2A37",
+ "button.secondaryBackground": "#223249",
+ "button.secondaryForeground": "#DCD7BA",
+ "checkbox.border": "#223249",
+ "debugToolBar.background": "#16161D",
+ "descriptionForeground": "#DCD7BA",
+ "diffEditor.insertedTextBackground": "#2B3328",
+ "dropdown.background": "#16161D",
+ "dropdown.border": "#16161D",
+ "editor.background": "#1F1F28",
+ "editor.findMatchBackground": "#2D4F67",
+ "editor.findMatchBorder": "#FF9E3B",
+ "editor.findMatchHighlightBackground": "#2D4F67",
+ "editor.foreground": "#DCD7BA",
+ "editorHoverWidget.highlightForeground": "#658594",
+ "editorInlayHint.foreground": "#727169",
+ "editorInlayHint.background": "#1F1F28",
+ "editor.lineHighlightBackground": "#2A2A37",
+ "editorLineNumber.activeForeground": "#957FB8",
+ "editorGutter.addedBackground": "#76946A",
+ "editorGutter.deletedBackground": "#C34043",
+ "editorGutter.modifiedBackground": "#DCA561",
+ "editor.wordHighlightBackground": "#3636464d",
+ "editor.wordHighlightBorder": "#54546D",
+ "editor.wordHighlightStrongBackground": "#3636464d",
+ "editor.wordHighlightStrongBorder": "#54546D",
+ "editor.selectionBackground": "#223249",
+ "editor.selectionHighlightBackground": "#363646",
+ "editor.selectionHighlightBorder": "#54546D",
+ "editorBracketMatch.background": "#16161D",
+ "editorBracketMatch.border": "#54546D",
+ "editorBracketHighlight.foreground1": "#957FB8",
+ "editorBracketHighlight.foreground2": "#FFA066",
+ "editorBracketHighlight.foreground3": "#7E9CD8",
+ "editorBracketHighlight.foreground4": "#D27E99",
+ "editorBracketHighlight.foreground5": "#E6C384",
+ "editorBracketHighlight.foreground6": "#7AA89F",
+ "editorBracketHighlight.unexpectedBracket.foreground": "#FF5D62",
+ "editorBracketPairGuide.activeBackground1": "#957FB8",
+ "editorBracketPairGuide.activeBackground2": "#FFA066",
+ "editorBracketPairGuide.activeBackground3": "#7E9CD8",
+ "editorBracketPairGuide.activeBackground4": "#D27E99",
+ "editorBracketPairGuide.activeBackground5": "#E6C384",
+ "editorBracketPairGuide.activeBackground6": "#7AA89F",
+ "editorCursor.background": "#DCD7BA",
+ "editorCursor.foreground": "#DCD7BA",
+ "editorError.foreground": "#E82424",
+ "editorGroup.border": "#16161D",
+ "editorGroupHeader.tabsBackground": "#16161D",
+ "editorHoverWidget.background": "#1F1F28",
+ "editorHoverWidget.border": "#2A2A37",
+ "editorIndentGuide.activeBackground": "#363646",
+ "editorIndentGuide.background": "#2A2A37",
+ "editorLineNumber.foreground": "#54546D",
+ "editorMarkerNavigation.background": "#363646",
+ "editorRuler.foreground": "#363646",
+ "editorSuggestWidget.background": "#223249",
+ "editorSuggestWidget.border": "#223249",
+ "editorSuggestWidget.selectedBackground": "#2D4F67",
+ "editorWarning.foreground": "#FF9E3B",
+ "editorWhitespace.foreground": "#1F1F28",
+ "editorWidget.background": "#1f1f28",
+ "focusBorder": "#223249",
+ "gitDecoration.ignoredResourceForeground": "#727169",
+ "input.background": "#16161D",
+ "list.activeSelectionBackground": "#363646",
+ "list.activeSelectionForeground": "#DCD7BA",
+ "list.focusBackground": "#2A2A37",
+ "list.focusForeground": "#DCD7BA",
+ "list.highlightForeground": "#7E9CD8",
+ "list.hoverBackground": "#363646",
+ "list.hoverForeground": "#DCD7BA",
+ "list.inactiveSelectionBackground": "#2A2A37",
+ "list.inactiveSelectionForeground": "#DCD7BA",
+ "list.warningForeground": "#FF9E3B",
+ "menu.foreground": "#DCD7BA",
+ "menu.separatorBackground": "#16161D",
+ "minimapGutter.addedBackground": "#76946A",
+ "minimapGutter.deletedBackground": "#C34043",
+ "minimapGutter.modifiedBackground": "#DCA561",
+ "panel.border": "#16161D",
+ "sideBar.border": "#16161D",
+ "panelSectionHeader.background": "#1f1f28",
+ "peekView.border": "#54546D",
+ "peekViewEditor.background": "#2A2A37",
+ "peekViewEditor.matchHighlightBackground": "#2D4F67",
+ "peekViewResult.background": "#363646",
+ "scrollbar.shadow": "#363646",
+ "scrollbarSlider.activeBackground": "#6f6f9080",
+ "scrollbarSlider.background": "#54546D66",
+ "scrollbarSlider.hoverBackground": "#54546D80",
+ "settings.focusedRowBackground": "#363646",
+ "settings.headerForeground": "#DCD7BA",
+ "sideBar.background": "#1F1F28",
+ "sideBar.foreground": "#DCD7BA",
+ "sideBarSectionHeader.background": "#363646",
+ "sideBarSectionHeader.foreground": "#DCD7BA",
+ "statusBar.background": "#16161D",
+ "statusBar.debuggingBackground": "#E82424",
+ "statusBar.debuggingBorder": "#957FB8",
+ "statusBar.debuggingForeground": "#DCD7BA",
+ "statusBar.foreground": "#C8C093",
+ "statusBar.noFolderBackground": "#1f1f28",
+ "statusBarItem.hoverBackground": "#363646",
+ "statusBarItem.remoteBackground": "#2D4F67",
+ "statusBarItem.remoteForeground": "#DCD7BA",
+ "tab.activeBackground": "#363646",
+ "tab.activeForeground": "#DCD7BA",
+ "tab.border": "#16161d",
+ "tab.hoverBackground": "#54546D",
+ "tab.inactiveBackground": "#1f1f28",
+ "tab.unfocusedHoverBackground": "#2A2A37",
+ "terminal.ansiBlack": "#1F1F28",
+ "terminal.ansiBlue": "#658594",
+ "terminal.ansiBrightBlack": "#2A2A37",
+ "terminal.ansiBrightBlue": "#7FB4CA",
+ "terminal.ansiBrightCyan": "#A3D4D5",
+ "terminal.ansiBrightGreen": "#98BB6C",
+ "terminal.ansiBrightMagenta": "#D27E99",
+ "terminal.ansiBrightRed": "#FF5D62",
+ "terminal.ansiBrightWhite": "#DCD7BA",
+ "terminal.ansiBrightYellow": "#E6C384",
+ "terminal.ansiCyan": "#9CABCA",
+ "terminal.ansiGreen": "#76946A",
+ "terminal.ansiMagenta": "#957FB8",
+ "terminal.ansiRed": "#E82424",
+ "terminal.ansiWhite": "#DCD7BA",
+ "terminal.ansiYellow": "#FF9E3B",
+ "terminal.background": "#1F1F28",
+ "terminal.border": "#16161D",
+ "terminal.foreground": "#DCD7BA",
+ "terminal.selectionBackground": "#223249",
+ "textBlockQuote.background": "#1F1F28",
+ "textBlockQuote.border": "#16161D",
+ "textLink.foreground": "#6A9589",
+ "textPreformat.foreground": "#FF9E3B",
+ "titleBar.activeBackground": "#363646",
+ "titleBar.activeForeground": "#DCD7BA",
+ "titleBar.inactiveBackground": "#1F1F28",
+ "titleBar.inactiveForeground": "#DCD7BA",
+ "walkThrough.embeddedEditorBackground": "#1F1F28"
+ },
+ "tokenColors": [
+ {
+ "name": "Comment",
+ "scope": [
+ "comment",
+ "punctuation.definition.comment"
+ ],
+ "settings": {
+ "foreground": "#727169"
+ }
+ },
+ {
+ "name": "Variables",
+ "scope": [
+ "variable",
+ "string constant.other.placeholder"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ },
+ {
+ "name": "Colors",
+ "scope": [
+ "constant.other.color"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "Invalid",
+ "scope": [
+ "invalid",
+ "invalid.illegal"
+ ],
+ "settings": {
+ "foreground": "#E82424"
+ }
+ },
+ {
+ "name": "Storage - Type",
+ "scope": [
+ "storage.type"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Storage - Modifier",
+ "scope": [
+ "storage.modifier"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Control Keyword",
+ "scope": [
+ "keyword.control.flow",
+ "keyword.control.conditional",
+ "keyword.control.loop"
+ ],
+ "settings": {
+ "foreground": "#957FB8",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Operator, Misc",
+ "scope": [
+ "keyword.control",
+ "constant.other.color",
+ "meta.tag",
+ "keyword.other.template",
+ "keyword.other.substitution",
+ "keyword.other"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "ini file definition",
+ "scope": [
+ "keyword.other.definition.ini"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "Operator, Misc",
+ "scope": [
+ "keyword.control.trycatch"
+ ],
+ "settings": {
+ "foreground": "#FF5D62",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Identifiers",
+ "scope": [
+ "keyword.other.unit",
+ "keyword.operator"
+ ],
+ "settings": {
+ "foreground": "#C0A36E"
+ }
+ },
+ {
+ "name": "Punctuation, Brace",
+ "scope": [
+ "punctuation",
+ "punctuation.definition.tag",
+ "punctuation.separator.inheritance.php",
+ "punctuation.definition.tag.html",
+ "punctuation.definition.tag.begin.html",
+ "punctuation.definition.tag.end.html",
+ "punctuation.section.embedded",
+ "meta.brace",
+ "keyword.operator.type.annotation",
+ "keyword.operator.namespace"
+ ],
+ "settings": {
+ "foreground": "#9CABCA"
+ }
+ },
+ {
+ "name": "Tag",
+ "scope": [
+ "entity.name.tag",
+ "meta.tag.sgml"
+ ],
+ "settings": {
+ "foreground": "#E6C384"
+ }
+ },
+ {
+ "name": "HTML Tag",
+ "scope": [
+ "entity.name.tag.html"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Function, Special Method",
+ "scope": [
+ "entity.name.function",
+ "meta.function-call",
+ "variable.function",
+ "support.function",
+ "keyword.other.special-method"
+ ],
+ "settings": {
+ "foreground": "#7E9CD8"
+ }
+ },
+ {
+ "name": "Macto",
+ "scope": [
+ "entity.name.function.macro"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "Block Level Variables",
+ "scope": [
+ "meta.block variable.other"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ },
+ {
+ "name": "Other Variable",
+ "scope": [
+ "support.other.variable"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ },
+ {
+ "name": "String Link",
+ "scope": [
+ "string.other.link"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "Constant, Function Argument, Tag Attribute, Embedded",
+ "scope": [
+ "constant.numeric",
+ "constant.language",
+ "support.constant",
+ "constant.character",
+ "constant.escape"
+ ],
+ "settings": {
+ "foreground": "#7FB4CA"
+ }
+ },
+ {
+ "name": "Boolean",
+ "scope": [
+ "constant.language.boolean"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "Number",
+ "scope": [
+ "constant.numeric"
+ ],
+ "settings": {
+ "foreground": "#D27E99"
+ }
+ },
+ {
+ "name": "String, Symbols, Inherited Class, Markup Heading",
+ "scope": [
+ "string",
+ "punctuation.definition.string",
+ "constant.other.symbol",
+ "constant.other.key",
+ "entity.other.inherited-class",
+ "markup.heading",
+ "markup.inserted.git_gutter",
+ "meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js",
+ "markup.inline.raw.string"
+ ],
+ "settings": {
+ "foreground": "#98BB6C"
+ }
+ },
+ {
+ "name": "Class, Support",
+ "scope": [
+ "entity.name",
+ "support.type",
+ "support.class",
+ "support.other.namespace.use.php",
+ "meta.use.php",
+ "support.other.namespace.php",
+ "support.type.sys-types"
+ ],
+ "settings": {
+ "foreground": "#7AA89F"
+ }
+ },
+ {
+ "name": "Namespace, Module",
+ "scope": [
+ "entity.name.type.module",
+ "entity.name.namespace"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ },
+ {
+ "name": "Go import",
+ "scope": [
+ "entity.name.import.go"
+ ],
+ "settings": {
+ "foreground": "#98BB6C"
+ }
+ },
+ {
+ "name": "Property",
+ "scope": [
+ "variable.other.property"
+ ],
+ "settings": {
+ "foreground": "#E6C384"
+ }
+ },
+ {
+ "name": "Import",
+ "scope": [
+ "keyword.control.import",
+ "keyword.import",
+ "meta.import"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "CSS Class and Support",
+ "scope": [
+ "source.css support.type.property-name",
+ "source.sass support.type.property-name",
+ "source.scss support.type.property-name",
+ "source.less support.type.property-name",
+ "source.stylus support.type.property-name",
+ "source.postcss support.type.property-name"
+ ],
+ "settings": {
+ "foreground": "#7AA89F"
+ }
+ },
+ {
+ "name": "Sub-methods",
+ "scope": [
+ "entity.name.module.js",
+ "variable.import.parameter.js",
+ "variable.other.class.js"
+ ],
+ "settings": {
+ "foreground": "#FF5D62"
+ }
+ },
+ {
+ "name": "Language methods",
+ "scope": [
+ "variable.language"
+ ],
+ "settings": {
+ "foreground": "#FF5D62"
+ }
+ },
+ {
+ "name": "entity.name.method.js",
+ "scope": [
+ "entity.name.method.js"
+ ],
+ "settings": {
+ "foreground": "#7E9CD8"
+ }
+ },
+ {
+ "name": "meta.method.js",
+ "scope": [
+ "meta.class-method.js entity.name.function.js",
+ "variable.function.constructor"
+ ],
+ "settings": {
+ "foreground": "#7E9CD8"
+ }
+ },
+ {
+ "name": "Attributes",
+ "scope": [
+ "entity.other.attribute-name"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "HTML Attributes",
+ "scope": [
+ "entity.other.attribute-name.html",
+ "entity.other.attribute-name",
+ "invalid.deprecated.entity.other.attribute-name.html"
+ ],
+ "settings": {
+ "foreground": "#E6C384"
+ }
+ },
+ {
+ "name": "CSS Classes",
+ "scope": [
+ "entity.other.attribute-name.class"
+ ],
+ "settings": {
+ "foreground": "#E6C384"
+ }
+ },
+ {
+ "name": "CSS ID's",
+ "scope": [
+ "source.sass keyword.control"
+ ],
+ "settings": {
+ "foreground": "#7FB4CA"
+ }
+ },
+ {
+ "name": "Inserted",
+ "scope": [
+ "markup.inserted"
+ ],
+ "settings": {
+ "foreground": "#76946A"
+ }
+ },
+ {
+ "name": "Deleted",
+ "scope": [
+ "markup.deleted"
+ ],
+ "settings": {
+ "foreground": "#C34043"
+ }
+ },
+ {
+ "name": "Changed",
+ "scope": [
+ "markup.changed"
+ ],
+ "settings": {
+ "foreground": "#DCA561"
+ }
+ },
+ {
+ "name": "Regular Expressions",
+ "scope": [
+ "string.regexp"
+ ],
+ "settings": {
+ "foreground": "#7FB4CA"
+ }
+ },
+ {
+ "name": "Escape Characters",
+ "scope": [
+ "constant.character.escape"
+ ],
+ "settings": {
+ "foreground": "#7FB4CA"
+ }
+ },
+ {
+ "name": "URL",
+ "scope": [
+ "*url*",
+ "*link*",
+ "*uri*"
+ ],
+ "settings": {
+ "fontStyle": "underline"
+ }
+ },
+ {
+ "name": "Decorators",
+ "scope": [
+ "tag.decorator.js entity.name.tag.js",
+ "tag.decorator.js punctuation.definition.tag.js"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "ES7 Bind Operator",
+ "scope": [
+ "source.js constant.other.object.key.js string.unquoted.label.js"
+ ],
+ "settings": {
+ "foreground": "#FF5D62"
+ }
+ },
+ {
+ "name": "JSON Key - Level 0",
+ "scope": [
+ "source.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#D27E99"
+ }
+ },
+ {
+ "name": "JSON Key - Level 1",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#E6C384"
+ }
+ },
+ {
+ "name": "JSON Key - Level 2",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "JSON Key - Level 3",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#FF5D62"
+ }
+ },
+ {
+ "name": "JSON Key - Level 4",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "JSON Key - Level 5",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#7E9CD8"
+ }
+ },
+ {
+ "name": "JSON Key - Level 6",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#D27E99"
+ }
+ },
+ {
+ "name": "JSON Key - Level 7",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "JSON Key - Level 8",
+ "scope": [
+ "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json"
+ ],
+ "settings": {
+ "foreground": "#98BB6C"
+ }
+ },
+ {
+ "name": "Markdown - Plain",
+ "scope": [
+ "text.html.markdown",
+ "punctuation.definition.list_item.markdown"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ },
+ {
+ "name": "Markdown - Markup Raw Inline",
+ "scope": [
+ "text.html.markdown markup.inline.raw.markdown"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Markdown - Markup Raw Inline Punctuation",
+ "scope": [
+ "text.html.markdown markup.inline.raw.markdown punctuation.definition.raw.markdown"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Markdown - Heading",
+ "scope": [
+ "markdown.heading",
+ "entity.name.section.markdown",
+ "markup.heading.markdown"
+ ],
+ "settings": {
+ "foreground": "#7E9CD8"
+ }
+ },
+ {
+ "name": "Markup - Italic",
+ "scope": [
+ "markup.italic"
+ ],
+ "settings": {
+ "fontStyle": "italic",
+ "foreground": "#E46876"
+ }
+ },
+ {
+ "name": "Markup - Bold",
+ "scope": [
+ "markup.bold",
+ "markup.bold string"
+ ],
+ "settings": {
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Markup - Bold-Italic",
+ "scope": [
+ "markup.bold markup.italic",
+ "markup.italic markup.bold",
+ "markup.quote markup.bold",
+ "markup.bold markup.italic string",
+ "markup.italic markup.bold string",
+ "markup.quote markup.bold string"
+ ],
+ "settings": {
+ "fontStyle": "bold",
+ "foreground": "#E46876"
+ }
+ },
+ {
+ "name": "Markup - Underline",
+ "scope": [
+ "markup.underline"
+ ],
+ "settings": {
+ "fontStyle": "underline",
+ "foreground": "#7FB4CA"
+ }
+ },
+ {
+ "name": "Markdown - Blockquote",
+ "scope": [
+ "markup.quote punctuation.definition.blockquote.markdown"
+ ],
+ "settings": {
+ "foreground": "#727169"
+ }
+ },
+ {
+ "name": "Markup - Quote",
+ "scope": [
+ "markup.quote"
+ ],
+ "settings": {
+ "fontStyle": "italic"
+ }
+ },
+ {
+ "name": "Markdown - Link",
+ "scope": [
+ "string.other.link.title.markdown"
+ ],
+ "settings": {
+ "foreground": "#FFA066"
+ }
+ },
+ {
+ "name": "Markdown - Link Description",
+ "scope": [
+ "string.other.link.description.title.markdown"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Markdown - Link Anchor",
+ "scope": [
+ "constant.other.reference.link.markdown"
+ ],
+ "settings": {
+ "foreground": "#E6C384"
+ }
+ },
+ {
+ "name": "Markup - Raw Block",
+ "scope": [
+ "markup.raw.block"
+ ],
+ "settings": {
+ "foreground": "#957FB8"
+ }
+ },
+ {
+ "name": "Markdown - Raw Block Fenced",
+ "scope": [
+ "markup.raw.block.fenced.markdown"
+ ],
+ "settings": {
+ "foreground": "#727169"
+ }
+ },
+ {
+ "name": "Markdown - Fenced Bode Block",
+ "scope": [
+ "punctuation.definition.fenced.markdown"
+ ],
+ "settings": {
+ "foreground": "#727169"
+ }
+ },
+ {
+ "name": "Markdown - Fenced Bode Block Variable",
+ "scope": [
+ "markup.raw.block.fenced.markdown",
+ "variable.language.fenced.markdown",
+ "punctuation.section.class.end"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ },
+ {
+ "name": "Markdown - Fenced Language",
+ "scope": [
+ "variable.language.fenced.markdown"
+ ],
+ "settings": {
+ "foreground": "#727169"
+ }
+ },
+ {
+ "name": "Markdown - Separator",
+ "scope": [
+ "meta.separator"
+ ],
+ "settings": {
+ "fontStyle": "bold",
+ "foreground": "#9CABCA"
+ }
+ },
+ {
+ "name": "Markup - Table",
+ "scope": [
+ "markup.table"
+ ],
+ "settings": {
+ "foreground": "#DCD7BA"
+ }
+ }
+ ],
+ "semanticTokenColors": {
+ "parameter": "#DCD7BA",
+ "variable": "#DCD7BA",
+ "arithmetic": "#C0A36E",
+ "method": "#7E9CD8",
+ "function": "#7E9CD8",
+ "operator": "#C0A36E",
+ "parameter.declaration": "#E6C384",
+ "parameter.definition": "#E6C384",
+ "variable.readonly": "#FFA066",
+ "variable.readonly.local": "#DCD7BA",
+ "variable.readonly.defaultLibrary": "#7FB4CA",
+ "macro": "#FFA066",
+ "keyword.controlFlow": {
+ "foreground": "#957FB8",
+ "fontStyle": "bold"
+ }
+ }
+}
diff --git a/src/lib/kanagawa.ts b/src/lib/kanagawa.ts
new file mode 100644
index 0000000..038a893
--- /dev/null
+++ b/src/lib/kanagawa.ts
@@ -0,0 +1,5 @@
+import fs from 'fs';
+
+export const kanagawa_dark = JSON.parse(
+ fs.readFileSync('./src/lib/kanagawa.json', 'utf-8')
+)
\ No newline at end of file
diff --git a/src/lib/server/article.ts b/src/lib/server/article.ts
new file mode 100644
index 0000000..5c5ae8b
--- /dev/null
+++ b/src/lib/server/article.ts
@@ -0,0 +1,22 @@
+import { compile, escapeSvelte } from "mdsvex";
+import { createHighlighter } from "shiki";
+import { kanagawa_dark as theme } from "$lib/kanagawa"
+
+
+const highlighter = await createHighlighter({
+ themes: [theme],
+ langs: ["javascript", "typescript", "shell"],
+});
+
+export default async function compileArticle(code: string) {
+ return compile(code, {
+ highlight: {
+ highlighter: async (code: string, lang = "text") => {
+ const html = escapeSvelte(
+ highlighter.codeToHtml(code, { lang, theme }),
+ );
+ return html;
+ },
+ },
+ });
+}
\ No newline at end of file
diff --git a/src/lib/server/database/get_connection.ts b/src/lib/server/database/get_connection.ts
index b8eee44..8cadd60 100644
--- a/src/lib/server/database/get_connection.ts
+++ b/src/lib/server/database/get_connection.ts
@@ -14,6 +14,6 @@ const pool = new Pool({ connectionString });
export const getConnection = () => pool;
-import init from '$lib/server/database/init_db';
+import init_db from '$lib/server/database/init';
import PG from '$lib/server/database';
-await init(await PG(pool));
\ No newline at end of file
+await init_db(await PG(pool));
\ No newline at end of file
diff --git a/src/lib/server/database/init_db.ts b/src/lib/server/database/init.ts
similarity index 87%
rename from src/lib/server/database/init_db.ts
rename to src/lib/server/database/init.ts
index a5d3185..f57c908 100644
--- a/src/lib/server/database/init_db.ts
+++ b/src/lib/server/database/init.ts
@@ -1,8 +1,8 @@
// initialize
import type { Postgres } from '$lib/server/database';
import fs from 'fs';
-import { compile } from 'mdsvex';
import { execSync } from 'child_process';
+import compile from '$lib/server/article';
export default async function init(db: Postgres) {
if (fs.existsSync('./articles/')) {
@@ -95,35 +95,35 @@ export default async function init(db: Postgres) {
console.log(`Table ${schema.name} already exists`);
}
}
+ } catch (err) {
+ console.error(err);
+ await db.rollback();
+ } finally {
await db.commit();
+ }
- const articleFiles: ArticleFileItem[] = [];
- function scanDir(path: string) {
- const files = fs.readdirSync(path);
- for (const file of files) {
- const dir = `${path}/${file}`;
- const stat = fs.statSync(dir);
- if (stat.isDirectory()) {
- scanDir(dir);
- } else {
- articleFiles.push({ path: `${path}/${file}`, id: file });
- }
+ const articleFiles: ArticleFileItem[] = [];
+ function scanDir(path: string) {
+ const files = fs.readdirSync(path);
+ for (const file of files) {
+ const dir = `${path}/${file}`;
+ const stat = fs.statSync(dir);
+ if (stat.isDirectory()) {
+ scanDir(dir);
+ } else {
+ articleFiles.push({ path: `${path}/${file}`, id: file.replace('.md', '') });
}
}
- scanDir('./articles/article');
+ }
+ scanDir('./articles/article');
- await db.query('update tag set ref_count = 0');
- db.commit();
+ await db.query('update tag set ref_count = 0');
- for (const { path, id } of articleFiles) {
+ for (const { path, id } of articleFiles) {
+ await db.begin();
+ try {
const res = await db.query('select * from article where id = $1', [id]);
- const compiled = await compile(fs.readFileSync(path, 'utf-8'), {
- highlight: {
- highlighter: (code: string, lang: string) => {
- return `${code}
`;
- }
- }
- });
+ const compiled = await compile(fs.readFileSync(path, 'utf-8'));
const title = compiled.data.fm.title;
const category = path.split('/')[3];
@@ -134,7 +134,7 @@ export default async function init(db: Postgres) {
const publish = compiled.data.fm.publish;
const content = compiled.code
.replace(/>{@html ``}<\/pre>/g, '
');
+ .replace(/<\/code>`}<\/pre>/g, '')
if (res.rowCount == 0) {
console.log(`New article: ${id}`);
await db.query(
@@ -142,6 +142,7 @@ export default async function init(db: Postgres) {
[id, title, category, released_at, updated_at, tags, image, publish, content]
);
} else if (res.rows[0].updated_at < updated_at) {
+ // } else if (true) {
console.log(`Update article: ${id}`);
await db.query(
'update article set title = $2, category = $3, released_at = $4, updated_at = $5, tags = $6, image = $7, publish = $8, content = $9 where id = $1',
@@ -157,15 +158,15 @@ export default async function init(db: Postgres) {
db.query('update tag set ref_count = ref_count + 1 where name = $1', [tag]);
}
}
+ } catch (err) {
+ console.log(err);
+ await db.rollback();
+ } finally {
+ await db.commit();
}
- await db.commit();
-
- } catch (err) {
- console.error(err);
- await db.rollback();
- } finally {
- await db.release();
}
+
+ await db.release();
}
type ArticleFileItem = {
diff --git a/src/routes/api/fetch_articles/+server.ts b/src/routes/api/fetch_articles/+server.ts
index 7264e6c..51f4283 100644
--- a/src/routes/api/fetch_articles/+server.ts
+++ b/src/routes/api/fetch_articles/+server.ts
@@ -8,7 +8,7 @@ import {
import PG from '$lib/server/database';
// import { building } from '$app/environment';
-import init from '$lib/server/database/init_db';
+import init_db from '$lib/server/database/init';
export const POST: RequestHandler = async ({ url, locals }) => {
const token = url.searchParams.get('token');
@@ -17,6 +17,6 @@ export const POST: RequestHandler = async ({ url, locals }) => {
return error(401, 'Unauthorized');
}
- await init(await PG(locals.db));
+ await init_db(await PG(locals.db));
return new Response(String(token));
};