summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hipis/packages/source/hwp/hwp/reader/commonmark.scm88
-rw-r--r--hipis/packages/source/hwp/hwp/site.scm123
-rw-r--r--hipis/packages/source/hwp/hwp/static/css/simple.min.css1
-rw-r--r--hipis/packages/source/hwp/hwp/static/css/syntax-highlight.css88
-rw-r--r--hipis/packages/source/hwp/hwp/static/images/favicon.icobin0 -> 15406 bytes
-rw-r--r--hipis/packages/source/hwp/hwp/utils.scm51
6 files changed, 335 insertions, 16 deletions
diff --git a/hipis/packages/source/hwp/hwp/reader/commonmark.scm b/hipis/packages/source/hwp/hwp/reader/commonmark.scm
new file mode 100644
index 0000000..05666a4
--- /dev/null
+++ b/hipis/packages/source/hwp/hwp/reader/commonmark.scm
@@ -0,0 +1,88 @@
1(define-module (hwp reader commonmark)
2 #:use-module (haunt post)
3 #:use-module (haunt reader)
4 #:use-module (haunt reader commonmark)
5
6 #:use-module (commonmark)
7
8 #:use-module (sxml simple)
9
10 #:use-module (ice-9 match)
11
12 #:use-module (sxml match)
13 #:use-module (sxml transform)
14 #:use-module (syntax-highlight)
15 #:use-module (syntax-highlight c)
16 #:use-module (syntax-highlight css)
17 #:use-module (syntax-highlight gitignore)
18 #:use-module (syntax-highlight lisp)
19 #:use-module (syntax-highlight scheme)
20 #:use-module (syntax-highlight xml)
21
22 #:export (commonmark-reader*
23 lexers-custom
24 lexers-code))
25
26(define lexers-code
27 (make-parameter
28 `((scheme . ,lex-scheme)
29 (lisp . ,lex-lisp)
30 (xml . ,lex-xml)
31 (c . ,lex-c)
32 (css . ,lex-css)
33 (gitignore . ,lex-gitignore))))
34
35(define lexers-custom
36 (make-parameter
37 `((notice . ,(lambda (source)
38 `(div (@ (class "notice"))
39 ,(commonmark->sxml source))))
40 (aside . ,(lambda (source)
41 `(aside ,(commonmark->sxml source))))
42 (custom-html . ,(lambda (source)
43 (cdr (xml->sxml source)))))))
44
45(define (handle-highlight-code name source)
46 (let ((lexer (assoc-ref (lexers-code) name)))
47 (if lexer
48 (highlights->sxml
49 (highlight lexer source))
50 #f)))
51
52(define (handle-custom-block name source)
53 (let ((lexer (assoc-ref (lexers-custom) name)))
54 (if lexer
55 (lexer source)
56 #f)))
57
58(define (handle-block . tree)
59 (sxml-match tree
60 ((pre (code (@ (class ,class) . ,attrs) ,source))
61 (let* ((name (string->symbol
62 (string-drop class (string-length "language-"))))
63 (highlight-code (handle-highlight-code name source))
64 (custom-block (handle-custom-block name source)))
65 (cond
66 (custom-block custom-block)
67 (#t `(pre (code (@ ,@attrs)
68 ,(or highlight-code
69 source)))))))
70 (,other other)))
71
72(define %commonmark-rules
73 `((pre . ,handle-block)
74 (*text* . ,(lambda (_ x) x))
75 (*default* . ,(lambda (. x) x))))
76
77(define (post-process-commonmark sxml)
78 (pre-post-order sxml %commonmark-rules))
79
80(define commonmark-reader*
81 (make-reader (make-file-extension-matcher "md")
82 (lambda (file)
83 (call-with-input-file file
84 (lambda (port)
85 (values (read-metadata-headers port)
86 (post-process-commonmark
87 (commonmark->sxml port))))))))
88
diff --git a/hipis/packages/source/hwp/hwp/site.scm b/hipis/packages/source/hwp/hwp/site.scm
index 7fdb2f0..0d2d06b 100644
--- a/hipis/packages/source/hwp/hwp/site.scm
+++ b/hipis/packages/source/hwp/hwp/site.scm
@@ -1,32 +1,123 @@
1(define-module (hwp site) 1(define-module (hwp site)
2 #:use-module (hwp utils)
3 #:use-module (hwp reader commonmark)
4
2 #:use-module (haunt asset) 5 #:use-module (haunt asset)
3 #:use-module (haunt builder blog) 6 #:use-module (haunt builder blog)
4 #:use-module (haunt builder atom) 7 #:use-module (haunt builder atom)
5 #:use-module (haunt builder assets) 8 #:use-module (haunt builder assets)
9 #:use-module (haunt builder flat-pages)
6 #:use-module (haunt reader commonmark) 10 #:use-module (haunt reader commonmark)
11 #:use-module (haunt artifact)
12 #:use-module (haunt reader)
13
7 #:use-module (haunt site) 14 #:use-module (haunt site)
15 #:use-module (haunt post)
16
17 #:use-module (sxml simple)
8 18
9 #:use-module (ice-9 match) 19 #:use-module (ice-9 match)
10 20
11 #:export (hipis-site)) 21 #:export (hipis-site))
12 22
23(define menu (make-parameter '()))
24
25(define dir-css (static-path "css/"))
26(define dir-images (static-path "images/"))
27
28(define (hipis-default-layout site title body)
29 `((doctype "html")
30 (head
31 (meta (@ (charset "utf-8")))
32 (link (@ (rel "icon")
33 (type "image/x-icon")
34 (href ,(static-image "favicon.ico"))))
35 ,@(map (lambda (x)
36 `(link (@ (rel "stylesheet")
37 (href ,(static-css x)))))
38 (list "syntax-highlight.css"
39 "simple.min.css"))
40 (title ,(string-append title " — " (site-title site))))
41 (body
42 (header
43 ,(menu)
44 (h1 (a (@ (style "text-decoration: none;") (href "/")) ,(site-title site)))
45 (p "Un-employable lisp enjoyer 🦎"))
46 (main ,body)
47 (footer
48 (p "Built with " (a (@ (href "https://dthompson.us/projects/haunt.html")
49 (target "_blank")) "Haunt")
50 ", " (a (@ (href "https://simplecss.org/")
51 (target "_blank")) "Simple.css")
52 " and guix " (a (@ (href "https://git.jdlugosz.com/hipis/hipis-system/tree/hipis.scm#n150")
53 (target "_blank")) "hipis-service-type."))
54 (p "Jakub Dlugosz ©")))))
55
56(define (hipis-default-post-template post)
57 `(article
58 (h2 ,(post-ref post 'title))
59 (p ,(date->string* (post-date post)) " - " ,(post-ref post 'author))
60 (section
61 ,(post-sxml post))))
62
63(define (hipis-default-collection-template site title posts prefix)
64 (define (post-uri post)
65 (string-append (or prefix "") "/"
66 (site-post-slug site post) ".html"))
67
68 `((h3 ,title)
69 (ul
70 ,@(map (lambda (post)
71 `(li
72 (a (@ (href ,(post-uri post)))
73 ,(post-ref post 'title)
74 " — "
75 ,(date->string* (post-date post)))))
76 posts))))
77
78(define (hipis-default-pagination-template site body previous-page next-page)
79 `(,@body
80 (div
81 ,(if previous-page
82 `(a (@ (href ,previous-page)) "← Previous")
83 '())
84 " — "
85 ,(if next-page
86 `(a (@ (href ,next-page)) "Next →")
87 '()))))
88
89(define hipis-theme
90 (theme #:name "Hipis"
91 #:layout hipis-default-layout
92 #:post-template hipis-default-post-template
93 #:collection-template hipis-default-collection-template
94 #:pagination-template hipis-default-pagination-template))
13 95
14(define (hipis-site site-directory build-directory) 96(define (hipis-site site-directory build-directory)
15 (build-site 97 (parameterize ((menu (generate-menu (string-append site-directory "menu/"))))
16 (site #:title "Built with Guile" 98 (build-site
17 #:domain "jdlugosz.com" 99 (site #:title "Jakub Dlugosz"
18 #:default-metadata 100 #:domain "jdlugosz.com"
19 '((author . "Jakub Długosz") 101 #:default-metadata
20 (email . "jdlugosz963@gmail.com")) 102 '((author . "Jakub Długosz")
21 #:readers (list commonmark-reader) 103 (email . "jdlugosz963@gmail.com"))
22 #:builders (list (blog) 104 #:readers (list commonmark-reader*)
23 (atom-feed) 105 #:builders (list (blog #:theme hipis-theme
24 (atom-feeds-by-tag) 106 #:prefix "/blog")
25 (static-directory (string-append site-directory 107 (atom-feed)
26 "/assets/images") 108 (atom-feeds-by-tag)
27 "/assets/images")) 109 (flat-pages (string-append site-directory
28 #:build-directory build-directory 110 "menu")
29 #:posts-directory (string-append site-directory 111 #:template hipis-default-layout)
30 "/posts")))) 112 (static-directory (string-append site-directory
113 "/assets/images")
114 static-image-url)
115 (static-directory dir-images
116 static-image-url)
117 (static-directory dir-css
118 static-css-url))
119 #:build-directory build-directory
120 #:posts-directory (string-append site-directory
121 "/posts")))))
31 122
32 123
diff --git a/hipis/packages/source/hwp/hwp/static/css/simple.min.css b/hipis/packages/source/hwp/hwp/static/css/simple.min.css
new file mode 100644
index 0000000..fa50a54
--- /dev/null
+++ b/hipis/packages/source/hwp/hwp/static/css/simple.min.css
@@ -0,0 +1 @@
:root,::backdrop{--sans-font:-apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Nimbus Sans L",Roboto,"Noto Sans","Segoe UI",Arial,Helvetica,"Helvetica Neue",sans-serif;--mono-font:Consolas,Menlo,Monaco,"Andale Mono","Ubuntu Mono",monospace;--standard-border-radius:5px;--bg:#fff;--accent-bg:#f5f7ff;--text:#212121;--text-light:#585858;--border:#898ea4;--accent:#0d47a1;--accent-hover:#1266e2;--accent-text:var(--bg);--code:#d81b60;--preformatted:#444;--marked:#fd3;--disabled:#efefef}@media (prefers-color-scheme:dark){:root,::backdrop{color-scheme:dark;--bg:#212121;--accent-bg:#2b2b2b;--text:#dcdcdc;--text-light:#ababab;--accent:#ffb300;--accent-hover:#ffe099;--accent-text:var(--bg);--code:#f06292;--preformatted:#ccc;--disabled:#111}img,video{opacity:.8}}*,:before,:after{box-sizing:border-box}textarea,select,input,progress{-webkit-appearance:none;-moz-appearance:none;appearance:none}html{font-family:var(--sans-font);scroll-behavior:smooth}body{color:var(--text);background-color:var(--bg);grid-template-columns:1fr min(45rem,90%) 1fr;margin:0;font-size:1.15rem;line-height:1.5;display:grid}body>*{grid-column:2}body>header{background-color:var(--accent-bg);border-bottom:1px solid var(--border);text-align:center;grid-column:1/-1;padding:0 .5rem 2rem}body>header>:only-child{margin-block-start:2rem}body>header h1{max-width:1200px;margin:1rem auto}body>header p{max-width:40rem;margin:1rem auto}main{padding-top:1.5rem}body>footer{color:var(--text-light);text-align:center;border-top:1px solid var(--border);margin-top:4rem;padding:2rem 1rem 1.5rem;font-size:.9rem}h1{font-size:3rem}h2{margin-top:3rem;font-size:2.6rem}h3{margin-top:3rem;font-size:2rem}h4{font-size:1.44rem}h5{font-size:1.15rem}h6{font-size:.96rem}p{margin:1.5rem 0}p,h1,h2,h3,h4,h5,h6{overflow-wrap:break-word}h1,h2,h3{line-height:1.1}@media only screen and (width<=720px){h1{font-size:2.5rem}h2{font-size:2.1rem}h3{font-size:1.75rem}h4{font-size:1.25rem}}a,a:visited{color:var(--accent)}a:hover{text-decoration:none}button,.button,a.button,input[type=submit],input[type=reset],input[type=button],label[type=button]{border:1px solid var(--accent);background-color:var(--accent);color:var(--accent-text);padding:.5rem .9rem;line-height:normal;text-decoration:none}.button[aria-disabled=true],input:disabled,textarea:disabled,select:disabled,button[disabled]{cursor:not-allowed;background-color:var(--disabled);border-color:var(--disabled);color:var(--text-light)}input[type=range]{padding:0}abbr[title]{cursor:help;text-decoration-line:underline;text-decoration-style:dotted}button:enabled:hover,.button:not([aria-disabled=true]):hover,input[type=submit]:enabled:hover,input[type=reset]:enabled:hover,input[type=button]:enabled:hover,label[type=button]:hover{background-color:var(--accent-hover);border-color:var(--accent-hover);cursor:pointer}.button:focus-visible,button:focus-visible:where(:enabled),input:enabled:focus-visible:where([type=submit],[type=reset],[type=button]){outline:2px solid var(--accent);outline-offset:1px}header>nav{padding:1rem 0 0;font-size:1rem;line-height:2}header>nav ul,header>nav ol{flex-flow:wrap;place-content:space-around center;align-items:center;margin:0;padding:0;list-style-type:none;display:flex}header>nav ul li,header>nav ol li{display:inline-block}header>nav a,header>nav a:visited{border:1px solid var(--border);border-radius:var(--standard-border-radius);color:var(--text);margin:0 .5rem 1rem;padding:.1rem 1rem;text-decoration:none;display:inline-block}header>nav a:hover,header>nav a.current,header>nav a[aria-current=page]{border-color:var(--accent);color:var(--accent);cursor:pointer}@media only screen and (width<=720px){header>nav a{border:none;padding:0;line-height:1;text-decoration:underline}}aside,details,pre,progress{background-color:var(--accent-bg);border:1px solid var(--border);border-radius:var(--standard-border-radius);margin-bottom:1rem}aside{float:right;width:30%;margin-inline-start:15px;padding:0 15px;font-size:1rem}[dir=rtl] aside{float:left}@media only screen and (width<=720px){aside{float:none;width:100%;margin-inline-start:0}}article,fieldset,dialog{border:1px solid var(--border);border-radius:var(--standard-border-radius);margin-bottom:1rem;padding:1rem}article h2:first-child,section h2:first-child{margin-top:1rem}section{border-top:1px solid var(--border);border-bottom:1px solid var(--border);margin:3rem 0;padding:2rem 1rem}section+section,section:first-child{border-top:0;padding-top:0}section:last-child{border-bottom:0;padding-bottom:0}details{padding:.7rem 1rem}summary{cursor:pointer;word-break:break-all;margin:-.7rem -1rem;padding:.7rem 1rem;font-weight:700}details[open]>summary+*{margin-top:0}details[open]>summary{margin-bottom:.5rem}details[open]>:last-child{margin-bottom:0}table{border-collapse:collapse;margin:1.5rem 0}figure>table{width:max-content}td,th{border:1px solid var(--border);text-align:start;padding:.5rem}th{background-color:var(--accent-bg);font-weight:700}tr:nth-child(2n){background-color:var(--accent-bg)}table caption{margin-bottom:.5rem;font-weight:700}textarea,select,input,button,.button{font-size:inherit;border-radius:var(--standard-border-radius);box-shadow:none;max-width:100%;margin-bottom:.5rem;padding:.5rem;font-family:inherit;display:inline-block}textarea,select,input{color:var(--text);background-color:var(--bg);border:1px solid var(--border)}label{display:block}textarea:not([cols]){width:100%}select:not([multiple]){background-image:linear-gradient(45deg,transparent 49%,var(--text)51%),linear-gradient(135deg,var(--text)51%,transparent 49%);background-position:calc(100% - 15px),calc(100% - 10px);background-repeat:no-repeat;background-size:5px 5px,5px 5px;padding-inline-end:25px}[dir=rtl] select:not([multiple]){background-position:10px,15px}input[type=checkbox],input[type=radio]{vertical-align:middle;width:min-content;position:relative}input[type=checkbox]+label,input[type=radio]+label{display:inline-block}input[type=radio]{border-radius:100%}input[type=checkbox]:checked,input[type=radio]:checked{background-color:var(--accent)}input[type=checkbox]:checked:after{content:" ";border-right:solid var(--bg).08em;border-bottom:solid var(--bg).08em;background-color:#0000;border-radius:0;width:.18em;height:.32em;font-size:1.8em;position:absolute;top:.05em;left:.17em;transform:rotate(45deg)}input[type=radio]:checked:after{content:" ";background-color:var(--bg);border-radius:100%;width:.25em;height:.25em;font-size:32px;position:absolute;top:.125em;left:.125em}@media only screen and (width<=720px){textarea,select,input{width:100%}}input[type=color]{height:2.5rem;padding:.2rem}input[type=file]{border:0}hr{background:var(--border);border:none;height:1px;margin:1rem auto}mark{border-radius:var(--standard-border-radius);background-color:var(--marked);color:#000;padding:2px 5px}mark a{color:#0d47a1}img,video{border-radius:var(--standard-border-radius);max-width:100%;height:auto}figure{margin:0;display:block;overflow-x:auto}figure>img,figure>picture>img{margin-inline:auto;display:block}figcaption{text-align:center;color:var(--text-light);margin-block:1rem;font-size:.9rem}blockquote{border-inline-start:.35rem solid var(--accent);color:var(--text-light);margin-block:2rem;margin-inline:2rem 0;padding:.4rem .8rem;font-style:italic}cite{color:var(--text-light);font-size:.9rem;font-style:normal}dt{color:var(--text-light)}code,pre,pre span,kbd,samp{font-family:var(--mono-font);color:var(--code)}kbd{color:var(--preformatted);border:1px solid var(--preformatted);border-bottom:3px solid var(--preformatted);border-radius:var(--standard-border-radius);padding:.1rem .4rem}pre{color:var(--preformatted);max-width:100%;padding:1rem 1.4rem;overflow:auto}pre code{color:var(--preformatted);background:0 0;margin:0;padding:0}progress{width:100%}progress:indeterminate{background-color:var(--accent-bg)}progress::-webkit-progress-bar{border-radius:var(--standard-border-radius);background-color:var(--accent-bg)}progress::-webkit-progress-value{border-radius:var(--standard-border-radius);background-color:var(--accent)}progress::-moz-progress-bar{border-radius:var(--standard-border-radius);background-color:var(--accent);transition-property:width;transition-duration:.3s}progress:indeterminate::-moz-progress-bar{background-color:var(--accent-bg)}dialog{max-width:40rem;margin:auto}dialog::backdrop{background-color:var(--bg);opacity:.8}@media only screen and (width<=720px){dialog{max-width:100%;margin:auto 1em}}sup,sub{vertical-align:baseline;position:relative}sup{top:-.4em}sub{top:.3em}.notice{background:var(--accent-bg);border:2px solid var(--border);border-radius:var(--standard-border-radius);margin:2rem 0;padding:1.5rem}
diff --git a/hipis/packages/source/hwp/hwp/static/css/syntax-highlight.css b/hipis/packages/source/hwp/hwp/static/css/syntax-highlight.css
new file mode 100644
index 0000000..199de4e
--- /dev/null
+++ b/hipis/packages/source/hwp/hwp/static/css/syntax-highlight.css
@@ -0,0 +1,88 @@
1:root {
2 --color-rose: #d6336c;
3 --color-navy: #005f87;
4 --color-orange: #d68c02;
5 --color-forest: #00743f;
6 --color-dark-gray: #333333;
7 --color-purple: #6f42c1;
8 --color-gray: #6c757d;
9 --color-red: #d9534f;
10 --color-gold: #b58900;
11 --color-teal: #007b83;
12}
13
14@media (prefers-color-scheme: dark) {
15 :root {
16 --color-rose: #ff79c6;
17 --color-navy: #8be9fd;
18 --color-orange: #ffb86c;
19 --color-forest: #50fa7b;
20 --color-dark-gray: #f8f8f2;
21 --color-purple: #bd93f9;
22 --color-gray: #6272a4;
23 --color-red: #ff5555;
24 --color-gold: #f1fa8c;
25 --color-teal: #66d9ef;
26 }
27}
28
29.syntax-attribute,
30.syntax-element,
31.syntax-keyword {
32 color: var(--color-rose);
33}
34
35.syntax-builtin,
36.syntax-entity,
37.syntax-ident,
38.syntax-prelude,
39.syntax-builtin-property {
40 color: var(--color-navy);
41}
42
43.syntax-cdc,
44.syntax-cdo,
45.syntax-id,
46.syntax-range {
47 color: var(--color-orange);
48}
49
50.syntax-class,
51.syntax-function,
52.syntax-selector {
53 color: var(--color-forest);
54}
55
56.syntax-close,
57.syntax-colon,
58.syntax-comma,
59.syntax-open,
60.syntax-semi {
61 color: var(--color-dark-gray);
62}
63
64.syntax-color,
65.syntax-number,
66.syntax-symbol {
67 color: var(--color-purple);
68}
69
70.syntax-comment,
71.syntax-multi-line-comment {
72 color: var(--color-gray);
73}
74
75.syntax-important {
76 color: var(--color-red);
77}
78
79.syntax-multi,
80.syntax-string,
81.syntax-special,
82.syntax-multi-line {
83 color: var(--color-gold);
84}
85
86.syntax-property {
87 color: var(--color-teal);
88}
diff --git a/hipis/packages/source/hwp/hwp/static/images/favicon.ico b/hipis/packages/source/hwp/hwp/static/images/favicon.ico
new file mode 100644
index 0000000..37a1741
--- /dev/null
+++ b/hipis/packages/source/hwp/hwp/static/images/favicon.ico
Binary files differ
diff --git a/hipis/packages/source/hwp/hwp/utils.scm b/hipis/packages/source/hwp/hwp/utils.scm
new file mode 100644
index 0000000..7c6f879
--- /dev/null
+++ b/hipis/packages/source/hwp/hwp/utils.scm
@@ -0,0 +1,51 @@
1(define-module (hwp utils)
2 #:use-module (ice-9 ftw)
3 #:use-module (ice-9 string-fun)
4 #:use-module (srfi srfi-26)
5
6 #:export (static-path
7 generate-menu
8 static-css
9 static-css-url
10 static-image
11 static-image-url))
12
13(define (menu-entries project-dir)
14 (map
15 (lambda (x) (let* ((name (string-drop-right x 3))
16 (html-file (string-append
17 name
18 ".html"))
19 (name-menu (string-upcase
20 (string-replace-substring name
21 "-" " "))))
22 (cons html-file name-menu)))
23 (scandir project-dir
24 (cut string-suffix? ".md" <>))))
25
26(define (generate-menu project-dir)
27 `(nav ,@(map (lambda (entry)
28 `(a (@ (href ,(car entry)))
29 ,(cdr entry)))
30 (menu-entries project-dir))))
31
32(define (static-path file)
33 (let ((files (filter
34 (lambda (path)
35 (access? path 0))
36 (map (lambda (path) (string-append path "/hwp/static/" file))
37 %load-path))))
38 (cond
39 ((not (pair? files)) (error "static-file-path: doesn't found anything!"))
40 ((> (length files) 1) (error "static-file-path: found more then one file!"))
41 (#t (car files)))))
42
43
44(define static-css-url "/static/css/")
45(define static-image-url "/static/assets/images/")
46
47(define (static-image name)
48 (string-append static-image-url name))
49
50(define (static-css name)
51 (string-append static-css-url name))