From aea4c7fda4cc6d746515a0aea6972a0914f9aedd Mon Sep 17 00:00:00 2001 From: jdlugosz963 Date: Sun, 19 May 2024 21:42:03 +0200 Subject: Add simple.css and markdown support for this. --- .../packages/source/hwp/hwp/reader/commonmark.scm | 88 +++++++++++++++ hipis/packages/source/hwp/hwp/site.scm | 123 ++++++++++++++++++--- .../source/hwp/hwp/static/css/simple.min.css | 1 + .../source/hwp/hwp/static/css/syntax-highlight.css | 88 +++++++++++++++ .../source/hwp/hwp/static/images/favicon.ico | Bin 0 -> 15406 bytes hipis/packages/source/hwp/hwp/utils.scm | 51 +++++++++ 6 files changed, 335 insertions(+), 16 deletions(-) create mode 100644 hipis/packages/source/hwp/hwp/reader/commonmark.scm create mode 100644 hipis/packages/source/hwp/hwp/static/css/simple.min.css create mode 100644 hipis/packages/source/hwp/hwp/static/css/syntax-highlight.css create mode 100644 hipis/packages/source/hwp/hwp/static/images/favicon.ico create mode 100644 hipis/packages/source/hwp/hwp/utils.scm 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 @@ +(define-module (hwp reader commonmark) + #:use-module (haunt post) + #:use-module (haunt reader) + #:use-module (haunt reader commonmark) + + #:use-module (commonmark) + + #:use-module (sxml simple) + + #:use-module (ice-9 match) + + #:use-module (sxml match) + #:use-module (sxml transform) + #:use-module (syntax-highlight) + #:use-module (syntax-highlight c) + #:use-module (syntax-highlight css) + #:use-module (syntax-highlight gitignore) + #:use-module (syntax-highlight lisp) + #:use-module (syntax-highlight scheme) + #:use-module (syntax-highlight xml) + + #:export (commonmark-reader* + lexers-custom + lexers-code)) + +(define lexers-code + (make-parameter + `((scheme . ,lex-scheme) + (lisp . ,lex-lisp) + (xml . ,lex-xml) + (c . ,lex-c) + (css . ,lex-css) + (gitignore . ,lex-gitignore)))) + +(define lexers-custom + (make-parameter + `((notice . ,(lambda (source) + `(div (@ (class "notice")) + ,(commonmark->sxml source)))) + (aside . ,(lambda (source) + `(aside ,(commonmark->sxml source)))) + (custom-html . ,(lambda (source) + (cdr (xml->sxml source))))))) + +(define (handle-highlight-code name source) + (let ((lexer (assoc-ref (lexers-code) name))) + (if lexer + (highlights->sxml + (highlight lexer source)) + #f))) + +(define (handle-custom-block name source) + (let ((lexer (assoc-ref (lexers-custom) name))) + (if lexer + (lexer source) + #f))) + +(define (handle-block . tree) + (sxml-match tree + ((pre (code (@ (class ,class) . ,attrs) ,source)) + (let* ((name (string->symbol + (string-drop class (string-length "language-")))) + (highlight-code (handle-highlight-code name source)) + (custom-block (handle-custom-block name source))) + (cond + (custom-block custom-block) + (#t `(pre (code (@ ,@attrs) + ,(or highlight-code + source))))))) + (,other other))) + +(define %commonmark-rules + `((pre . ,handle-block) + (*text* . ,(lambda (_ x) x)) + (*default* . ,(lambda (. x) x)))) + +(define (post-process-commonmark sxml) + (pre-post-order sxml %commonmark-rules)) + +(define commonmark-reader* + (make-reader (make-file-extension-matcher "md") + (lambda (file) + (call-with-input-file file + (lambda (port) + (values (read-metadata-headers port) + (post-process-commonmark + (commonmark->sxml port)))))))) + 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 @@ (define-module (hwp site) + #:use-module (hwp utils) + #:use-module (hwp reader commonmark) + #:use-module (haunt asset) #:use-module (haunt builder blog) #:use-module (haunt builder atom) #:use-module (haunt builder assets) + #:use-module (haunt builder flat-pages) #:use-module (haunt reader commonmark) + #:use-module (haunt artifact) + #:use-module (haunt reader) + #:use-module (haunt site) + #:use-module (haunt post) + + #:use-module (sxml simple) #:use-module (ice-9 match) #:export (hipis-site)) +(define menu (make-parameter '())) + +(define dir-css (static-path "css/")) +(define dir-images (static-path "images/")) + +(define (hipis-default-layout site title body) + `((doctype "html") + (head + (meta (@ (charset "utf-8"))) + (link (@ (rel "icon") + (type "image/x-icon") + (href ,(static-image "favicon.ico")))) + ,@(map (lambda (x) + `(link (@ (rel "stylesheet") + (href ,(static-css x))))) + (list "syntax-highlight.css" + "simple.min.css")) + (title ,(string-append title " — " (site-title site)))) + (body + (header + ,(menu) + (h1 (a (@ (style "text-decoration: none;") (href "/")) ,(site-title site))) + (p "Un-employable lisp enjoyer 🦎")) + (main ,body) + (footer + (p "Built with " (a (@ (href "https://dthompson.us/projects/haunt.html") + (target "_blank")) "Haunt") + ", " (a (@ (href "https://simplecss.org/") + (target "_blank")) "Simple.css") + " and guix " (a (@ (href "https://git.jdlugosz.com/hipis/hipis-system/tree/hipis.scm#n150") + (target "_blank")) "hipis-service-type.")) + (p "Jakub Dlugosz ©"))))) + +(define (hipis-default-post-template post) + `(article + (h2 ,(post-ref post 'title)) + (p ,(date->string* (post-date post)) " - " ,(post-ref post 'author)) + (section + ,(post-sxml post)))) + +(define (hipis-default-collection-template site title posts prefix) + (define (post-uri post) + (string-append (or prefix "") "/" + (site-post-slug site post) ".html")) + + `((h3 ,title) + (ul + ,@(map (lambda (post) + `(li + (a (@ (href ,(post-uri post))) + ,(post-ref post 'title) + " — " + ,(date->string* (post-date post))))) + posts)))) + +(define (hipis-default-pagination-template site body previous-page next-page) + `(,@body + (div + ,(if previous-page + `(a (@ (href ,previous-page)) "← Previous") + '()) + " — " + ,(if next-page + `(a (@ (href ,next-page)) "Next →") + '())))) + +(define hipis-theme + (theme #:name "Hipis" + #:layout hipis-default-layout + #:post-template hipis-default-post-template + #:collection-template hipis-default-collection-template + #:pagination-template hipis-default-pagination-template)) (define (hipis-site site-directory build-directory) - (build-site - (site #:title "Built with Guile" - #:domain "jdlugosz.com" - #:default-metadata - '((author . "Jakub Długosz") - (email . "jdlugosz963@gmail.com")) - #:readers (list commonmark-reader) - #:builders (list (blog) - (atom-feed) - (atom-feeds-by-tag) - (static-directory (string-append site-directory - "/assets/images") - "/assets/images")) - #:build-directory build-directory - #:posts-directory (string-append site-directory - "/posts")))) + (parameterize ((menu (generate-menu (string-append site-directory "menu/")))) + (build-site + (site #:title "Jakub Dlugosz" + #:domain "jdlugosz.com" + #:default-metadata + '((author . "Jakub Długosz") + (email . "jdlugosz963@gmail.com")) + #:readers (list commonmark-reader*) + #:builders (list (blog #:theme hipis-theme + #:prefix "/blog") + (atom-feed) + (atom-feeds-by-tag) + (flat-pages (string-append site-directory + "menu") + #:template hipis-default-layout) + (static-directory (string-append site-directory + "/assets/images") + static-image-url) + (static-directory dir-images + static-image-url) + (static-directory dir-css + static-css-url)) + #:build-directory build-directory + #:posts-directory (string-append site-directory + "/posts"))))) 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 @@ +:root { + --color-rose: #d6336c; + --color-navy: #005f87; + --color-orange: #d68c02; + --color-forest: #00743f; + --color-dark-gray: #333333; + --color-purple: #6f42c1; + --color-gray: #6c757d; + --color-red: #d9534f; + --color-gold: #b58900; + --color-teal: #007b83; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-rose: #ff79c6; + --color-navy: #8be9fd; + --color-orange: #ffb86c; + --color-forest: #50fa7b; + --color-dark-gray: #f8f8f2; + --color-purple: #bd93f9; + --color-gray: #6272a4; + --color-red: #ff5555; + --color-gold: #f1fa8c; + --color-teal: #66d9ef; + } +} + +.syntax-attribute, +.syntax-element, +.syntax-keyword { + color: var(--color-rose); +} + +.syntax-builtin, +.syntax-entity, +.syntax-ident, +.syntax-prelude, +.syntax-builtin-property { + color: var(--color-navy); +} + +.syntax-cdc, +.syntax-cdo, +.syntax-id, +.syntax-range { + color: var(--color-orange); +} + +.syntax-class, +.syntax-function, +.syntax-selector { + color: var(--color-forest); +} + +.syntax-close, +.syntax-colon, +.syntax-comma, +.syntax-open, +.syntax-semi { + color: var(--color-dark-gray); +} + +.syntax-color, +.syntax-number, +.syntax-symbol { + color: var(--color-purple); +} + +.syntax-comment, +.syntax-multi-line-comment { + color: var(--color-gray); +} + +.syntax-important { + color: var(--color-red); +} + +.syntax-multi, +.syntax-string, +.syntax-special, +.syntax-multi-line { + color: var(--color-gold); +} + +.syntax-property { + color: var(--color-teal); +} 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 Binary files /dev/null and b/hipis/packages/source/hwp/hwp/static/images/favicon.ico 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 @@ +(define-module (hwp utils) + #:use-module (ice-9 ftw) + #:use-module (ice-9 string-fun) + #:use-module (srfi srfi-26) + + #:export (static-path + generate-menu + static-css + static-css-url + static-image + static-image-url)) + +(define (menu-entries project-dir) + (map + (lambda (x) (let* ((name (string-drop-right x 3)) + (html-file (string-append + name + ".html")) + (name-menu (string-upcase + (string-replace-substring name + "-" " ")))) + (cons html-file name-menu))) + (scandir project-dir + (cut string-suffix? ".md" <>)))) + +(define (generate-menu project-dir) + `(nav ,@(map (lambda (entry) + `(a (@ (href ,(car entry))) + ,(cdr entry))) + (menu-entries project-dir)))) + +(define (static-path file) + (let ((files (filter + (lambda (path) + (access? path 0)) + (map (lambda (path) (string-append path "/hwp/static/" file)) + %load-path)))) + (cond + ((not (pair? files)) (error "static-file-path: doesn't found anything!")) + ((> (length files) 1) (error "static-file-path: found more then one file!")) + (#t (car files))))) + + +(define static-css-url "/static/css/") +(define static-image-url "/static/assets/images/") + +(define (static-image name) + (string-append static-image-url name)) + +(define (static-css name) + (string-append static-css-url name)) -- cgit v1.2.3