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)); };