Refactoring
This commit is contained in:
parent
1e3833f7d0
commit
aa563e60ea
37 changed files with 472 additions and 2392 deletions
|
@ -1,23 +0,0 @@
|
|||
doctype html
|
||||
html(lang="en")
|
||||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
title Artur Gurgul - #{title}
|
||||
meta(name="author" content="Artur Gurgul")
|
||||
meta(name="description" content="This is my notepad")
|
||||
|
||||
link(rel="shortcut icon" href="/favicon.png")
|
||||
link(rel="alternate" type="application/atom+xml" title="#{site.data.theme.name}" href="#{site.url}/atom.xml")
|
||||
link(rel="stylesheet" href="/static/css/all.css")
|
||||
link(rel="stylesheet" href="/static/css/hightlight.css")
|
||||
body
|
||||
.container
|
||||
.sidebar
|
||||
include sidebar.pug
|
||||
.scroll
|
||||
.content
|
||||
h1.title= title
|
||||
#post!= content
|
||||
.footer
|
||||
include footer.pug
|
|
@ -1,2 +0,0 @@
|
|||
.disclaimer
|
||||
p © Artur Gurgul, 2024 — Public Domain Licence
|
|
@ -1,10 +0,0 @@
|
|||
nav
|
||||
h2(style="font-size: 20px; margin: 0px;") Hi. I'm
|
||||
a(href="/") Artur Gurgul
|
||||
h2(style="font-size: 15px; margin-top: -0.5em;") and this is my notepad.
|
||||
hr.hr-text(data-content="Contents")
|
||||
ul#blog-posts.posts
|
||||
each page in pages.filter(it => it.hidden != true && it.title != undefined )
|
||||
li
|
||||
span »
|
||||
a(href=page.url, style=(false ? "font-weight: bold;" : ""))= page.title
|
|
@ -1,7 +0,0 @@
|
|||
site:
|
||||
title: Artur Gurgul - {{article.title}}
|
||||
remote:
|
||||
type: ssh
|
||||
user: debian
|
||||
host: artur.gurgul.pro
|
||||
path: /var/www/artur.gurgul.pro
|
|
@ -1,672 +0,0 @@
|
|||
|
||||
@font-face {
|
||||
font-family: OpenSans;
|
||||
font-weight: italic;
|
||||
src: url('/media/opensans/opensans-italic-variable_font_wdth,wght.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: OpenSans;
|
||||
font-weight: normal;
|
||||
src: url('/media/opensans/opensans-regular-variable_font-wdth,wght.ttf');
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: sticky; top:0;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
/* margin: 0 auto; */
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 390px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
body,
|
||||
.content,
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body,
|
||||
.container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
box-sizing: border-box;
|
||||
border-right: 1px solid #DDD;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
.scroll {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: scroll
|
||||
}
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font: 14px/21px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
color: #444;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: #181818;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1 a,
|
||||
h2 a,
|
||||
h3 a,
|
||||
h4 a,
|
||||
h5 a,
|
||||
h6 a {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 46px;
|
||||
line-height: 50px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 35px;
|
||||
line-height: 40px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 28px;
|
||||
line-height: 34px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 21px;
|
||||
line-height: 30px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 17px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
}
|
||||
|
||||
.subheader {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
p img {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p.lead {
|
||||
font-size: 21px;
|
||||
line-height: 27px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
blockquote p {
|
||||
font-size: 17px;
|
||||
line-height: 24px;
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0px;
|
||||
padding: 0px 20px 0 15px;
|
||||
border-left: 2px solid #ddd;
|
||||
}
|
||||
|
||||
blockquote cite {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
blockquote cite:before {
|
||||
content: "\2014 \0020";
|
||||
}
|
||||
|
||||
blockquote cite a,
|
||||
blockquote cite a:visited,
|
||||
blockquote cite a:visited {
|
||||
color: #0060ad;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: solid #ddd;
|
||||
border-width: 1px 0 0;
|
||||
clear: both;
|
||||
margin: 10px 0 30px;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: #333;
|
||||
text-decoration: underline;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
p a,
|
||||
p a:visited {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none outside;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul.square,
|
||||
ul.circle,
|
||||
ul.disc {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
ul.square {
|
||||
list-style: square outside;
|
||||
}
|
||||
|
||||
ul.circle {
|
||||
list-style: circle outside;
|
||||
}
|
||||
|
||||
ul.disc {
|
||||
list-style: disc outside;
|
||||
}
|
||||
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ol,
|
||||
ol ul {
|
||||
margin: 4px 0 5px 30px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
ul ul li,
|
||||
ul ol li,
|
||||
ol ol li,
|
||||
ol ul li {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 18px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
ul.large li {
|
||||
line-height: 21px;
|
||||
}
|
||||
|
||||
li p {
|
||||
line-height: 21px;
|
||||
}
|
||||
|
||||
img.scale-with-grid {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
ul.tabs {
|
||||
display: block;
|
||||
margin: 0 0 20px 0;
|
||||
padding: 0;
|
||||
border-bottom: solid 1px #ddd;
|
||||
}
|
||||
|
||||
ul.tabs li {
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
float: left;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ul.tabs li a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
width: auto;
|
||||
height: 29px;
|
||||
padding: 0px 20px;
|
||||
line-height: 30px;
|
||||
border: solid 1px #ddd;
|
||||
border-width: 1px 1px 0 0;
|
||||
margin: 0;
|
||||
background: #f5f5f5;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
ul.tabs li a.active {
|
||||
background: #fff;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
top: -4px;
|
||||
padding-top: 4px;
|
||||
border-left-width: 1px;
|
||||
margin: 0 0 0 -1px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
ul.tabs-content {
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.tabs-content>li {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.tabs-content>li.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.tabs:before,
|
||||
ul.tabs:after {
|
||||
content: '\0020';
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
ul.tabs:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
ul.tabs {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
label span,
|
||||
legend span {
|
||||
font-weight: normal;
|
||||
font-size: 13px;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
|
||||
thead {
|
||||
border-bottom: solid #0060ad;
|
||||
font-weight: bold;
|
||||
color: #0060ad;
|
||||
}
|
||||
|
||||
thead th {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 16px;
|
||||
background-color: white;
|
||||
color: #222222;
|
||||
line-height: 24px;
|
||||
margin: 0;
|
||||
|
||||
border-top: 7px solid #0060ad;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: #181818;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h1.title {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 21px;
|
||||
line-height: 24px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 1em 0;
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0060ad;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0060ad;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #0060ad;
|
||||
}
|
||||
|
||||
table {
|
||||
font-size: inherit;
|
||||
font: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.posts {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
ul.posts {
|
||||
margin-top: 0;
|
||||
list-style-type: none;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
ul.posts li {
|
||||
line-height: 22px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
ul.posts span {
|
||||
font-family: 'Lucida Console', 'Andale Mono', monospace;
|
||||
color: #aaa;
|
||||
padding-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.site .footer {
|
||||
font-size: 80%;
|
||||
color: #666;
|
||||
border-top: 4px solid #eee;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
nav h1,
|
||||
nav h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#post pre {
|
||||
border: 0px solid #ddd;
|
||||
background-color: #005fad06 !important;
|
||||
padding: 0 .4em;
|
||||
margin-bottom: 20px !important;
|
||||
border-color: #005fad43 !important;
|
||||
}
|
||||
|
||||
#post ul,
|
||||
#post ol {
|
||||
margin-left: 1.35em;
|
||||
}
|
||||
|
||||
#post code {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eef;
|
||||
font-size: 85%;
|
||||
padding: 0 .2em;
|
||||
}
|
||||
|
||||
|
||||
#post pre code {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding-top: 25px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
|
||||
.sidebar p {
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
text {
|
||||
font: 500 12px/22px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
|
||||
/* path, rect {
|
||||
stroke: red;
|
||||
} */
|
||||
|
||||
g {
|
||||
font: 500 12px/22px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
/* stroke-width="2" */
|
||||
|
||||
.content {
|
||||
font: 400 16px/22px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
|
||||
padding-left: 40px;
|
||||
padding-top: 25px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
#home h2 {
|
||||
color: #0060ad;
|
||||
}
|
||||
|
||||
#post pre {
|
||||
background-color: white;
|
||||
border-left: 12px solid #eee;
|
||||
padding: 0 .8em;
|
||||
}
|
||||
|
||||
#post code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#stalker {
|
||||
float: inherit;
|
||||
}
|
||||
|
||||
.disclaimer {
|
||||
color: #aaa;
|
||||
font-weight: 700;
|
||||
font-size: smaller;
|
||||
text-align: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.highlight {
|
||||
background-color: white;
|
||||
color: #586e75;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.highlight .c {
|
||||
color: #586e75 !important;
|
||||
font-style: italic !important
|
||||
}
|
||||
|
||||
p:has(img) {
|
||||
background-color: #005fad06;
|
||||
border-left: 12px solid #005fad43;
|
||||
}
|
||||
|
||||
p > img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
p:has(svg) {
|
||||
background-color: #005fad06;
|
||||
border-left: 12px solid #005fad43;
|
||||
}
|
||||
|
||||
p > svg {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
|
||||
XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
background: #fff;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* Gray DOCTYPE selectors like WebKit */
|
||||
.xml .hljs-meta {
|
||||
color: #c0c0c0;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #007400;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-attribute,
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-name {
|
||||
color: #aa0d91;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #3F6E74;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #c41a16;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #0E0EFF;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-number {
|
||||
color: #1c00cf;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-meta {
|
||||
color: #643820;
|
||||
}
|
||||
|
||||
|
||||
.hljs-title.class_,
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-params {
|
||||
color: #5c2699;
|
||||
}
|
||||
|
||||
.hljs-attr {
|
||||
color: #836C28;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.hljs-formula {
|
||||
background-color: #eee;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #baeeba;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ffc8bd;
|
||||
}
|
||||
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #9b703f;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
|
@ -3,12 +3,12 @@ html(lang="en")
|
|||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
title Artur Gurgul - #{title}
|
||||
title Artur Gurgul - #{page.title}
|
||||
meta(name="author" content="Artur Gurgul")
|
||||
meta(name="description" content="This is my notepad")
|
||||
|
||||
link(rel="shortcut icon" href="/favicon.png")
|
||||
link(rel="alternate" type="application/atom+xml" title="#{site.data.theme.name}" href="#{site.url}/atom.xml")
|
||||
link(rel="alternate" type="application/atom+xml" title=page.title href="#{site.url}/atom.xml")
|
||||
link(rel="stylesheet" href="/static/css/all.css")
|
||||
link(rel="stylesheet" href="/static/css/hightlight.css")
|
||||
body
|
||||
|
@ -17,7 +17,7 @@ html(lang="en")
|
|||
include sidebar.pug
|
||||
.scroll
|
||||
.content
|
||||
h1.title= title
|
||||
#post!= content
|
||||
h1.title= page.title
|
||||
#post!= page.file.html
|
||||
.footer
|
||||
include footer.pug
|
||||
|
|
|
@ -4,7 +4,7 @@ nav
|
|||
h2(style="font-size: 15px; margin-top: -0.5em;") and this is my notepad.
|
||||
hr.hr-text(data-content="Contents")
|
||||
ul#blog-posts.posts
|
||||
each page in pages.filter(it => it.hidden != true && it.title != undefined )
|
||||
each page in context.pages
|
||||
li
|
||||
span »
|
||||
a(href=page.url, style=(false ? "font-weight: bold;" : ""))= page.title
|
||||
a(href=page.url, style=(page.isCurrent ? "font-weight: bold;" : ""))= page.title
|
||||
|
|
|
@ -1,28 +1,5 @@
|
|||
|
||||
@font-face {
|
||||
font-family: Montserrat;
|
||||
/* declare weights giving two values to specify a range */
|
||||
font-weight: 400 800;
|
||||
src: url(/static/fonts/Montserrat-VariableFont_wght.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Montserrat;
|
||||
/* declare weights giving two values to specify a range */
|
||||
font-weight: 400 800;
|
||||
font-style: italic;
|
||||
src: url(/static/fonts/Montserrat-Italic-VariableFont_wght.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Proto;
|
||||
/* declare weights giving two values to specify a range */
|
||||
font-weight: 400 800;
|
||||
src: url(/static/fonts/0xProto-Regular.ttf);
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: Montserrat, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
|
@ -136,7 +113,7 @@ h4,
|
|||
h5,
|
||||
h6 {
|
||||
color: #181818;
|
||||
font-family: Montserrat, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
@ -460,7 +437,7 @@ h4,
|
|||
h5,
|
||||
h6 {
|
||||
color: #181818;
|
||||
font-family: Montserrat, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
@ -531,7 +508,7 @@ ul.posts li {
|
|||
}
|
||||
|
||||
ul.posts span {
|
||||
font-family: 'Proto', monospace;
|
||||
font-family: monospace;
|
||||
color: #aaa;
|
||||
padding-right: 5px;
|
||||
font-size: 14px;
|
||||
|
@ -576,7 +553,7 @@ nav h2 {
|
|||
|
||||
.sidebar {
|
||||
padding-top: 25px;
|
||||
font-family: Montserrat, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
|
||||
.sidebar p {
|
||||
|
@ -588,7 +565,7 @@ nav h2 {
|
|||
}
|
||||
|
||||
text {
|
||||
font: 500 12px/22px Montserrat, sans-serif;
|
||||
font: 500 12px/22px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
|
||||
/* path, rect {
|
||||
|
@ -596,12 +573,12 @@ text {
|
|||
} */
|
||||
|
||||
g {
|
||||
font: 500 12px/22px Montserrat, sans-serif;
|
||||
font: 500 12px/22px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
/* stroke-width="2" */
|
||||
|
||||
.content {
|
||||
font: 400 16px/22px Montserrat, sans-serif;
|
||||
font: 400 16px/22px -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
|
||||
padding-left: 40px;
|
||||
padding-top: 25px;
|
||||
|
@ -678,7 +655,7 @@ pre {
|
|||
|
||||
code,
|
||||
pre {
|
||||
font-family: 'Proto', monospace;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
layout: default
|
||||
title: Content
|
||||
hidden: true
|
||||
---
|
||||
|
||||
# Content
|
||||
|
||||
there is my awasome content
|
1417
package-lock.json
generated
1417
package-lock.json
generated
File diff suppressed because it is too large
Load diff
25
package.json
25
package.json
|
@ -33,25 +33,22 @@
|
|||
},
|
||||
"homepage": "https://github.com/artur-gurgul-pro/sajt#readme",
|
||||
"dependencies": {
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0",
|
||||
"express": "^4.19.2",
|
||||
"fs-extra": "^11.2.0",
|
||||
"chalk": "^5.4.1",
|
||||
"commander": "^14.0.0",
|
||||
"express": "^5.1.0",
|
||||
"fs-extra": "^11.3.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"highlight.js": "^11.10.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"marked": "^14.0.0",
|
||||
"marked-highlight": "^2.1.4",
|
||||
"pug": "^3.0.3",
|
||||
"ssh2": "^1.15.0",
|
||||
"ssh2-sftp-client": "^11.0.0"
|
||||
"marked": "^15.0.12",
|
||||
"marked-highlight": "^2.2.1",
|
||||
"pug": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/express": "^5.0.2",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^22.13.5",
|
||||
"@types/node": "^22.15.30",
|
||||
"@types/pug": "^2.0.10",
|
||||
"electron": "^33.0.1",
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,32 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import yaml from 'js-yaml'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
export default class ProjectConfig {
|
||||
public config: any = {}
|
||||
public config: any
|
||||
|
||||
private __filename: string
|
||||
private __dirname: string
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
public load() {
|
||||
this.config = {
|
||||
this.config = {
|
||||
... this.read(),
|
||||
buildDir: './.build',
|
||||
ignore: [".build", ".sajt"]
|
||||
}
|
||||
|
||||
this.config.remote.port = 22
|
||||
this.config.remote.privateKey = fs.readFileSync(path.resolve(process.env.HOME ?? "", '.ssh/id_rsa'))
|
||||
this.__filename = fileURLToPath(import.meta.url)
|
||||
this.__dirname = path.dirname(this.__filename)
|
||||
this.config.defaultProjectPath = path.join(this.__dirname, '..', 'empty')
|
||||
}
|
||||
|
||||
read(): any {
|
||||
const __dirname = process.cwd()
|
||||
const configPath = path.join(__dirname, '.sajt/config.yaml')
|
||||
if (!fs.existsSync(configPath)) {
|
||||
return {}
|
||||
}
|
||||
const fileContents = fs.readFileSync(configPath, 'utf8')
|
||||
return yaml.load(fileContents)
|
||||
}
|
|
@ -1,12 +1,8 @@
|
|||
import { Command } from 'commander'
|
||||
import chalk from 'chalk'
|
||||
//import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import Project from './project.js'
|
||||
import { serve } from './serve.js'
|
||||
|
||||
const program = new Command()
|
||||
|
||||
let project = new Project()
|
||||
|
||||
program
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import Parser , {File} from "./renderer.js"
|
||||
|
||||
import hljs from 'highlight.js'
|
||||
import { marked } from 'marked'
|
||||
import { markedHighlight } from 'marked-highlight'
|
||||
|
@ -13,15 +15,19 @@ marked.use(markedHighlight({
|
|||
}
|
||||
}))
|
||||
|
||||
export function parseMD(file: string) {
|
||||
const fileContents = fs.readFileSync(path.join("./", file), 'utf8')
|
||||
export default class Markdown implements Parser {
|
||||
name = "md"
|
||||
|
||||
loadAsHTML(filePath: string): File {
|
||||
const fileContents = fs.readFileSync(path.join("./", filePath), 'utf8')
|
||||
const { data: metadata, content: markdownContent } = matter(fileContents)
|
||||
const htmlContent = marked(markdownContent)
|
||||
const htmlContent = marked(markdownContent, {async: false})
|
||||
|
||||
return {
|
||||
meta: metadata,
|
||||
content: htmlContent
|
||||
data: metadata,
|
||||
html: htmlContent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const renderer = new marked.Renderer()
|
||||
|
|
50
src/page.ts
Normal file
50
src/page.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import Renderer , {File} from "./renderer.js"
|
||||
import path from 'path'
|
||||
import utils from './utils.js'
|
||||
|
||||
export default class Page {
|
||||
file: File
|
||||
|
||||
/// /example/path
|
||||
dir: string[]
|
||||
|
||||
/// /example/path/file
|
||||
path: string
|
||||
|
||||
/// /example/path/file.html
|
||||
finalPath: string
|
||||
|
||||
/// file.html
|
||||
fileName: string
|
||||
|
||||
hidden: boolean
|
||||
title: string
|
||||
layout: string
|
||||
|
||||
constructor(filePath: string, renderer: Renderer) {
|
||||
this.file = renderer.loadAsHTML(filePath)
|
||||
|
||||
if (this.file.data?.path != null && this.file.data?.path != undefined) {
|
||||
this.path = path.join("/", this.file.data?.path)
|
||||
} else {
|
||||
const parsedPath = path.parse(filePath)
|
||||
const basePath = path.join("/", parsedPath.dir, parsedPath.name)
|
||||
this.path = basePath
|
||||
}
|
||||
|
||||
const parsedPath = path.parse(this.path)
|
||||
parsedPath.ext = '.html'
|
||||
parsedPath.base = `${parsedPath.name}${parsedPath.ext}`
|
||||
this.finalPath = path.format(parsedPath)
|
||||
|
||||
const dirArray = utils.pathToArray(this.finalPath)
|
||||
this.fileName = dirArray.pop() || ""
|
||||
dirArray.shift()
|
||||
this.dir = dirArray
|
||||
this.hidden = this.file.data?.hidden || false
|
||||
|
||||
// TODO: if tilte do not exists search in markdown for # title
|
||||
this.title = this.file.data.title
|
||||
this.layout = this.file.data.layout || "default"
|
||||
}
|
||||
}
|
|
@ -1,41 +1,83 @@
|
|||
import { fileURLToPath } from 'url'
|
||||
|
||||
import path from 'path'
|
||||
import { cp } from './utils.js'
|
||||
import { build } from './site.js'
|
||||
import ProjectConfig from './project-config.js'
|
||||
import ProjectConfig from './config.js'
|
||||
|
||||
|
||||
import fs from 'fs'
|
||||
import pug from 'pug'
|
||||
|
||||
import utils from "./utils.js"
|
||||
|
||||
import Markdown from './markdown.js'
|
||||
import Yaml from './yaml.js'
|
||||
import Page from './page.js'
|
||||
|
||||
export default class Project {
|
||||
public config = new ProjectConfig() // should be injected
|
||||
private __filename: string
|
||||
private __dirname: string
|
||||
private DEFAULT_PROJECT_PATH: string
|
||||
private config = new ProjectConfig()
|
||||
pages: Page[]
|
||||
|
||||
constructor() {
|
||||
// Get the directory of the current file
|
||||
this.__filename = fileURLToPath(import.meta.url)
|
||||
this.__dirname = path.dirname(this.__filename)
|
||||
|
||||
// Path relative to the script file's directory
|
||||
this.DEFAULT_PROJECT_PATH = path.join(this.__dirname, '..', 'empty')
|
||||
this.pages = this.loadPages()
|
||||
|
||||
console.log(this.pages.map(it=> {return {dir: it.dir, file: it.finalPath}}))
|
||||
}
|
||||
|
||||
new() {
|
||||
console.log("Initialize a new project")
|
||||
console.log(this.DEFAULT_PROJECT_PATH)
|
||||
cp(this.DEFAULT_PROJECT_PATH, ".")
|
||||
|
||||
console.log(this.config)
|
||||
this.config.load()
|
||||
}
|
||||
|
||||
existing() {
|
||||
this.config.load()
|
||||
cp(this.config.config.defaultProjectPath, ".")
|
||||
}
|
||||
|
||||
build() {
|
||||
this.config.load()
|
||||
build(this.config.config)
|
||||
|
||||
utils.removeDirectorySync(this.config.config.buildDir)
|
||||
utils.cp("./.sajt/static", path.join(this.config.config.buildDir, "static"))
|
||||
|
||||
for(const page of this.pages) {
|
||||
this.compile(page)
|
||||
}
|
||||
}
|
||||
|
||||
loadPages(): Page[] {
|
||||
const mdParser = new Markdown()
|
||||
const yamlParser = new Yaml()
|
||||
|
||||
let listMD = utils.getAllFilesWithExtension('.',".md", this.config.config.ignore)
|
||||
.map(path => new Page(path, mdParser))
|
||||
|
||||
let listYML = utils.getAllFilesWithExtension('.',".yml", this.config.config.ignore)
|
||||
.map(path => new Page(path, yamlParser))
|
||||
|
||||
return listMD.concat(listYML)
|
||||
}
|
||||
|
||||
compile(page: Page) {
|
||||
const output = path.join(this.config.config.buildDir, page.finalPath)
|
||||
|
||||
const compiledFunction = pug.compileFile(`.sajt/layouts/${page.layout}.pug`)
|
||||
|
||||
const data = {
|
||||
page,
|
||||
context: this.context(page)
|
||||
}
|
||||
|
||||
const dirname = path.dirname(output)
|
||||
if (!fs.existsSync(dirname)) {
|
||||
fs.mkdirSync(dirname, { recursive: true })
|
||||
}
|
||||
|
||||
const html = compiledFunction(data)
|
||||
fs.writeFileSync(output, html)
|
||||
console.log(`> ${output}`)
|
||||
}
|
||||
|
||||
context(page: Page): any {
|
||||
return {
|
||||
pages: this.pages.map(it => { return {
|
||||
title: it.title,
|
||||
isCurrent: page == it,
|
||||
url: it.finalPath,
|
||||
isDir: false
|
||||
}})
|
||||
}
|
||||
}
|
||||
}
|
10
src/renderer.ts
Normal file
10
src/renderer.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
export interface File {
|
||||
get html(): string
|
||||
get data(): { [key: string]: any }
|
||||
}
|
||||
|
||||
export default interface Renderer {
|
||||
get name(): string
|
||||
loadAsHTML(path: string): File
|
||||
}
|
|
@ -1,15 +1,11 @@
|
|||
import express from 'express'
|
||||
import { setWatcher } from './watch.js'
|
||||
//import { webdavMiddleware } from "./webdav.js"
|
||||
|
||||
const app = express()
|
||||
const PORT = process.env.PORT || 3000
|
||||
|
||||
export function serve() {
|
||||
app.use(express.static('./.build'))
|
||||
|
||||
//app.use(webdavMiddleware)
|
||||
|
||||
setWatcher(url => {
|
||||
console.log(url)
|
||||
})
|
||||
|
|
132
src/site.ts
132
src/site.ts
|
@ -1,132 +0,0 @@
|
|||
import fs from 'fs'
|
||||
import pug from 'pug'
|
||||
import path from 'path'
|
||||
|
||||
import { cp } from "./utils.js"
|
||||
import { parseMarkdown } from './markdown.js'
|
||||
import { getAllFilesWithExtension, pathToArray, parseYML } from './utils.js'
|
||||
import { parseMD } from './markdown.js'
|
||||
|
||||
function removeDirectorySync(directory: string) {
|
||||
try {
|
||||
fs.rmSync(directory, { recursive: true, force: true })
|
||||
console.log("Directory and its contents removed.")
|
||||
} catch (err: any) {
|
||||
console.error(`Error removing directory: ${err.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
function compile(template: string, content: any, output: string) {
|
||||
if (template == null) {
|
||||
console.error("Template is not defined, loading the default")
|
||||
template = "default"
|
||||
}
|
||||
const compiledFunction = pug.compileFile(`.sajt/layouts/${template}.pug`);
|
||||
const data = {
|
||||
...content,
|
||||
site: {posts: []}
|
||||
}
|
||||
|
||||
const dirname = path.dirname(output)
|
||||
if (!fs.existsSync(dirname)) {
|
||||
fs.mkdirSync(dirname, { recursive: true })
|
||||
}
|
||||
|
||||
const html = compiledFunction(data)
|
||||
fs.writeFileSync(output, html)
|
||||
console.log(`HTML has been rendered and saved to ${output}`);
|
||||
}
|
||||
|
||||
function compileData(template: string, content: object, output: string) {
|
||||
const compiledFunction = pug.compileFile(`.sajt/layouts/${template}.pug`)
|
||||
|
||||
const dirname = path.dirname(output)
|
||||
if (!fs.existsSync(dirname)) {
|
||||
fs.mkdirSync(dirname, { recursive: true })
|
||||
}
|
||||
|
||||
const html = compiledFunction(content)
|
||||
fs.writeFileSync(output, html)
|
||||
console.log(`HTML has been rendered and saved to ${output}`);
|
||||
}
|
||||
|
||||
function readMetadata(ignore: string[]) {
|
||||
let htmlExtension = "html"
|
||||
|
||||
let listMD = getAllFilesWithExtension('.',".md", ignore)
|
||||
.map(f => { return {
|
||||
pathMD: f,
|
||||
type: "md",
|
||||
data: {} as any,
|
||||
md: parseMD(f)
|
||||
} as any })
|
||||
|
||||
let listYML = getAllFilesWithExtension('.',".yml", ignore)
|
||||
.map(f => { return {
|
||||
pathMD: f,
|
||||
type: "yml",
|
||||
data: parseYML(f),
|
||||
md: {meta: {}}
|
||||
} as any })
|
||||
|
||||
let list = listMD.concat(listYML)
|
||||
|
||||
for(const site of list) {
|
||||
if (site.md.meta?.path != null && site.md.meta?.path != undefined) {
|
||||
site.path = path.join("/", site.md.meta.path)
|
||||
} else {
|
||||
const parsedPath = path.parse(site.pathMD)
|
||||
const basePath = path.join("/", parsedPath.dir, parsedPath.name)
|
||||
site.path = basePath
|
||||
}
|
||||
|
||||
// add proper extension
|
||||
const parsedPath = path.parse(site.path)
|
||||
parsedPath.ext = htmlExtension.startsWith('.') ? htmlExtension : `.${htmlExtension}`
|
||||
parsedPath.base = `${parsedPath.name}${parsedPath.ext}`
|
||||
site.path = path.format(parsedPath)
|
||||
|
||||
// add dirs metadata
|
||||
const dirArray = pathToArray(site.path)
|
||||
site.fileName = dirArray.pop()
|
||||
dirArray.shift()
|
||||
site.dir = dirArray
|
||||
site.meta = site.md.meta
|
||||
site.hidden = site.data?.hidden || false
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
export function build(config: any) {
|
||||
removeDirectorySync(config.buildDir)
|
||||
cp("./.sajt/static", path.join(config.buildDir, "static"))
|
||||
|
||||
let data = readMetadata(config.ignore)
|
||||
let pages = data.map(site => {
|
||||
return {
|
||||
title: site.meta.title,
|
||||
url: site.path
|
||||
}
|
||||
})
|
||||
|
||||
for(const site of data) {
|
||||
if (site.type == "md") {
|
||||
compile(site.meta.layout,
|
||||
{
|
||||
content: site.md.content,
|
||||
title: site.meta.title,
|
||||
hidden: false,
|
||||
pages
|
||||
},
|
||||
path.join(config.buildDir, site.path))
|
||||
} else if (site.type == "yml") {
|
||||
let data = {...site.data}
|
||||
delete data.layout
|
||||
parseMarkdown(data)
|
||||
compileData(site.data.layout,
|
||||
{data, pages, hidden: data.hidden},
|
||||
path.join(config.buildDir, site.path))
|
||||
}
|
||||
}
|
||||
}
|
36
src/ssh.ts
36
src/ssh.ts
|
@ -1,36 +0,0 @@
|
|||
/*const Client = require('ssh2-sftp-client')
|
||||
|
||||
async function uploadDirectory(serverConfig, localDirPath) {
|
||||
const sftp = new Client()
|
||||
await sftp.connect(serverConfig)
|
||||
try {
|
||||
await upload(sftp, config, localDirPath, serverConfig.path)
|
||||
} catch (err) {
|
||||
console.error(`Error: ${err.message}`)
|
||||
} finally {
|
||||
await sftp.end()
|
||||
console.log('Connection closed')
|
||||
}
|
||||
}
|
||||
|
||||
async function upload(sftp, config, localPath, remotePath) {
|
||||
|
||||
console.log('Connected to the server')
|
||||
|
||||
const files = fs.readdirSync(localPath)
|
||||
|
||||
for (const file of files) {
|
||||
const localFilePath = path.join(localPath, file)
|
||||
const remoteFilePath = `${remotePath}/${file}`
|
||||
|
||||
if (fs.statSync(localFilePath).isDirectory()) {
|
||||
await sftp.mkdir(remoteFilePath, true)
|
||||
await upload(sftp, config, localFilePath, remoteFilePath)
|
||||
} else {
|
||||
const fileContent = fs.readFileSync(localFilePath)
|
||||
await sftp.put(Buffer.from(fileContent), remoteFilePath)
|
||||
console.log(`File transferred successfully: ${localFilePath}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
28
src/utils.ts
28
src/utils.ts
|
@ -1,12 +1,7 @@
|
|||
import yaml from 'js-yaml'
|
||||
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export function parseYML(file: string) {
|
||||
const fileContents = fs.readFileSync(file, 'utf8')
|
||||
return yaml.load(fileContents)
|
||||
}
|
||||
|
||||
export function getAllFilesWithExtension(directory: string, extension: string, excludes: string[]): string[] {
|
||||
let results: string[] = []
|
||||
function readDirectory(directory: string) {
|
||||
|
@ -29,7 +24,6 @@ export function getAllFilesWithExtension(directory: string, extension: string, e
|
|||
return results
|
||||
}
|
||||
|
||||
// copyDirectory
|
||||
export function cp(source: string, destination: string) {
|
||||
fs.mkdirSync(destination, { recursive: true })
|
||||
const items = fs.readdirSync(source)
|
||||
|
@ -45,9 +39,23 @@ export function cp(source: string, destination: string) {
|
|||
})
|
||||
}
|
||||
|
||||
export function pathToArray(filePath: string) {
|
||||
// Normalize the file path to handle different OS path separators
|
||||
function removeDirectorySync(directory: string) {
|
||||
try {
|
||||
fs.rmSync(directory, { recursive: true, force: true })
|
||||
console.log("Directory and its contents removed.")
|
||||
} catch (err: any) {
|
||||
console.error(`Error removing directory: ${err.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
export function pathToArray(filePath: string):string[] {
|
||||
const normalizedPath = path.normalize(filePath)
|
||||
// Split the path into an array of directories
|
||||
return normalizedPath.split(path.sep)
|
||||
}
|
||||
|
||||
export default {
|
||||
pathToArray,
|
||||
cp,
|
||||
getAllFilesWithExtension,
|
||||
removeDirectorySync
|
||||
}
|
27
src/watch.ts
27
src/watch.ts
|
@ -2,34 +2,31 @@ import fs from 'fs'
|
|||
import path from 'path'
|
||||
|
||||
export function setWatcher(callback: (url: string) => void) {
|
||||
// Directory to watch
|
||||
const directoryPath = './';
|
||||
// Ensure the directory exists
|
||||
const directoryPath = './'
|
||||
if (!fs.existsSync(directoryPath)) {
|
||||
fs.mkdirSync(directoryPath, { recursive: true });
|
||||
fs.mkdirSync(directoryPath, { recursive: true })
|
||||
}
|
||||
console.log(`Watching for changes in: ${directoryPath}`);
|
||||
// Watch the directory for changes
|
||||
console.log(`Watching for changes in: ${directoryPath}`)
|
||||
|
||||
fs.watch(directoryPath, (eventType, filename) => {
|
||||
if (filename) {
|
||||
const fullPath = path.join(directoryPath, filename);
|
||||
console.log(`File ${filename} has been ${eventType}`);
|
||||
// Check if the file was added, changed, or deleted
|
||||
const fullPath = path.join(directoryPath, filename)
|
||||
console.log(`File ${filename} has been ${eventType}`)
|
||||
fs.stat(fullPath, (err, stats) => {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.log(`File ${filename} was deleted.`);
|
||||
console.log(`File ${filename} was deleted.`)
|
||||
} else {
|
||||
console.error(`Error checking file status: ${err.message}`);
|
||||
console.error(`Error checking file status: ${err.message}`)
|
||||
}
|
||||
} else {
|
||||
if (stats.isFile()) {
|
||||
console.log(`File ${filename} exists with size: ${stats.size} bytes`);
|
||||
console.log(`File ${filename} exists with size: ${stats.size} bytes`)
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
} else {
|
||||
console.log('Filename not provided, but change detected.');
|
||||
console.log('Filename not provided, but change detected.')
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
import { v2 as webdav } from 'webdav-server';
|
||||
|
||||
// 1. Create a user manager and add a user
|
||||
const userManager = new webdav.SimpleUserManager()
|
||||
const user = userManager.addUser('user', 'password', false)
|
||||
|
||||
// 2. Create a privilege manager
|
||||
const privilegeManager = new webdav.SimplePathPrivilegeManager()
|
||||
|
||||
// 3. Configure the WebDAV server
|
||||
const server = new webdav.WebDAVServer({
|
||||
// HTTP Digest authentication for better security
|
||||
httpAuthentication: new webdav.HTTPDigestAuthentication(userManager, 'default-realm'),
|
||||
privilegeManager
|
||||
})
|
||||
|
||||
// 4. Set up a physical file system folder (e.g., `./data`) as the root
|
||||
const publicFileSystem = new webdav.PhysicalFileSystem('./')
|
||||
|
||||
server.setFileSystem('/', publicFileSystem, (success) => {
|
||||
if (!success) {
|
||||
console.error('Failed to set file system')
|
||||
process.exit(1)
|
||||
}
|
||||
// Give the user all permissions on the root
|
||||
privilegeManager.setRights(user, '/', ['all'])
|
||||
});
|
||||
|
||||
export const webdavMiddleware = webdav.extensions.express("/", server)
|
||||
*/
|
20
src/yaml.ts
Normal file
20
src/yaml.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import yaml from 'js-yaml'
|
||||
import Renderer , {File} from "./renderer.js"
|
||||
import fs from 'fs'
|
||||
|
||||
export default class Yaml implements Renderer {
|
||||
name = "yml"
|
||||
|
||||
loadAsHTML(file: string): File {
|
||||
const fileContents = fs.readFileSync(file, 'utf8')
|
||||
|
||||
// let data = {...site.data}
|
||||
// delete data.layout
|
||||
// parseMarkdown(data)
|
||||
|
||||
return {
|
||||
data: yaml.load(fileContents) as { [key: string]: any },
|
||||
html: ""
|
||||
}
|
||||
}
|
||||
}
|
4
types/config.d.ts
vendored
4
types/config.d.ts
vendored
|
@ -1,7 +1,7 @@
|
|||
export default class ProjectConfig {
|
||||
config: any;
|
||||
private __filename;
|
||||
private __dirname;
|
||||
constructor();
|
||||
load(): void;
|
||||
getConfig(): any;
|
||||
read(): any;
|
||||
}
|
||||
|
|
2
types/context.d.ts
vendored
Normal file
2
types/context.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export default interface Context {
|
||||
}
|
11
types/markdown.d.ts
vendored
11
types/markdown.d.ts
vendored
|
@ -1,7 +1,6 @@
|
|||
export declare function parseMD(file: string): {
|
||||
meta: {
|
||||
[key: string]: any;
|
||||
};
|
||||
content: string | Promise<string>;
|
||||
};
|
||||
import Parser, { File } from "./renderer.js";
|
||||
export default class Markdown implements Parser {
|
||||
name: string;
|
||||
loadAsHTML(filePath: string): File;
|
||||
}
|
||||
export declare function parseMarkdown(obj: any): void;
|
||||
|
|
12
types/page.d.ts
vendored
Normal file
12
types/page.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
import Renderer, { File } from "./renderer.js";
|
||||
export default class Page {
|
||||
file: File;
|
||||
dir: string[];
|
||||
path: string;
|
||||
finalPath: string;
|
||||
fileName: string;
|
||||
hidden: boolean;
|
||||
title: string;
|
||||
layout: string;
|
||||
constructor(filePath: string, renderer: Renderer);
|
||||
}
|
10
types/parser.d.ts
vendored
Normal file
10
types/parser.d.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export interface File {
|
||||
get html(): string;
|
||||
get data(): {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
export default interface Parser {
|
||||
get name(): string;
|
||||
parse(path: string): File;
|
||||
}
|
12
types/project.d.ts
vendored
12
types/project.d.ts
vendored
|
@ -1,11 +1,11 @@
|
|||
import ProjectConfig from './project-config.js';
|
||||
import Page from './page.js';
|
||||
export default class Project {
|
||||
config: ProjectConfig;
|
||||
private __filename;
|
||||
private __dirname;
|
||||
private DEFAULT_PROJECT_PATH;
|
||||
private config;
|
||||
pages: Page[];
|
||||
constructor();
|
||||
new(): void;
|
||||
existing(): void;
|
||||
build(): void;
|
||||
loadPages(): Page[];
|
||||
compile(page: Page): void;
|
||||
context(page: Page): any;
|
||||
}
|
||||
|
|
10
types/renderer.d.ts
vendored
Normal file
10
types/renderer.d.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export interface File {
|
||||
get html(): string;
|
||||
get data(): {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
export default interface Renderer {
|
||||
get name(): string;
|
||||
loadAsHTML(path: string): File;
|
||||
}
|
9
types/utils.d.ts
vendored
9
types/utils.d.ts
vendored
|
@ -1,4 +1,11 @@
|
|||
export declare function parseYML(file: string): unknown;
|
||||
export declare function getAllFilesWithExtension(directory: string, extension: string, excludes: string[]): string[];
|
||||
export declare function cp(source: string, destination: string): void;
|
||||
declare function removeDirectorySync(directory: string): void;
|
||||
export declare function pathToArray(filePath: string): string[];
|
||||
declare const _default: {
|
||||
pathToArray: typeof pathToArray;
|
||||
cp: typeof cp;
|
||||
getAllFilesWithExtension: typeof getAllFilesWithExtension;
|
||||
removeDirectorySync: typeof removeDirectorySync;
|
||||
};
|
||||
export default _default;
|
||||
|
|
5
types/yaml.d.ts
vendored
Normal file
5
types/yaml.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import Renderer, { File } from "./renderer.js";
|
||||
export default class Yaml implements Renderer {
|
||||
name: string;
|
||||
loadAsHTML(file: string): File;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue