M assets/paper.css => assets/paper.css +0 -7
@@ 24,10 24,3 @@ body{counter-reset: section}
counter-increment: detail;
content: counter(section) "." counter(sub-section) "." counter(composite) "." counter(detail) " ";
}
-
-a {
- color: black;
-}
-a:visited {
- color: grey;
-}
M assets/simple.css => assets/simple.css +56 -32
@@ 17,7 17,10 @@
--text-light: #585858;
--border: #898EA4;
--accent: #0d47a1;
- --code: #d81b60;
+ --link: black;
+ --link-visited: gray;
+ /* --code: #d81b60; */
+ --code: #444;
--preformatted: #444;
--marked: #ffdd33;
--disabled: #efefef;
@@ 33,7 36,10 @@
--text: #dcdcdc;
--text-light: #ababab;
--accent: #ffb300;
- --code: #f06292;
+ --link: white;
+ --link-visited: gray;
+ /* --code: #f06292; */
+ --code: #ccc;
--preformatted: #ccc;
--disabled: #111;
}
@@ 112,6 118,19 @@ body > footer {
border-top: 1px solid var(--border);
}
+
+/* Prevent long strings from overflowing container */
+p, h1, h2, h3, h4, h5, h6 {
+ overflow-wrap: break-word;
+}
+
+/* Fix line height when title wraps */
+h1,
+h2,
+h3 {
+ line-height: 1.1;
+}
+
/* Format headers */
/* h1 { */
/* font-size: 3rem; */
@@ 139,36 158,24 @@ body > footer {
/* font-size: 0.96rem; */
/* } */
-/* Prevent long strings from overflowing container */
-p, h1, h2, h3, h4, h5, h6 {
- overflow-wrap: break-word;
-}
-
-/* Fix line height when title wraps */
-h1,
-h2,
-h3 {
- line-height: 1.1;
-}
-
/* Reduce header size on mobile */
-@media only screen and (max-width: 720px) {
- h1 {
- font-size: 2.5rem;
- }
-
- h2 {
- font-size: 2.1rem;
- }
-
- h3 {
- font-size: 1.75rem;
- }
-
- h4 {
- font-size: 1.25rem;
- }
-}
+/* @media only screen and (max-width: 720px) { */
+/* h1 { */
+/* font-size: 2.5rem; */
+/* } */
+
+/* h2 { */
+/* font-size: 2.1rem; */
+/* } */
+
+/* h3 { */
+/* font-size: 1.75rem; */
+/* } */
+
+/* h4 { */
+/* font-size: 1.25rem; */
+/* } */
+/* } */
/* Format links & buttons */
/* a, */
@@ 571,7 578,7 @@ pre span,
kbd,
samp {
font-family: var(--mono-font);
- /* color: var(--code); */
+ color: var(--code);
}
kbd {
@@ 590,6 597,10 @@ pre {
color: var(--preformatted);
}
+code {
+ font-size: 1rem;
+}
+
/* Fix embedded code within pre */
pre code {
/* color: var(--preformatted); */
@@ 674,3 685,16 @@ dialog::backdrop {
padding: 1.5rem;
margin: 2rem 0;
}
+
+a.invisible-link, a.invisible-link:visited {
+ text-decoration: none;
+ color: var(--link);
+}
+
+a {
+ color: var(--link);
+}
+
+a:visited {
+ color: var(--link-visited);
+}
A pages/contact.md => pages/contact.md +16 -0
@@ 0,0 1,16 @@
+title: contact
+---
+# Contact
+
+Here are my contacts:
+
+- **email:** andrew [-at-] this domain
+- **mastodon:** [@abcdw@fosstodon.org](https://fosstodon.org/@abcdw)
+- **tg:** @andrewtropin
+- **matrix:** [@abcdw:attendees.fosdem.org](https://matrix.to/#/@abcdw:attendees.fosdem.org)
+- **OpenPGP:** [D963A5A38A803D524461F91474830A276C328EC2](https://meta.sr.ht/~abcdw.pgp)
+
+For bug reports, patches and user support use mailing lists and chats
+of respective projects, please. This way more people can
+help/review/answer and more people can benefit having public access to
+those conversations.
A pages/guix.md => pages/guix.md +49 -0
@@ 0,0 1,49 @@
+title: guix
+---
+## Guix Installation ISO
+
+This is a basic installation image, but ci.guix.gnu.org substitute
+server is changed to ci.guix.trop.in mirror.
+
+[http://files.trop.in/iso/](http://files.trop.in/iso/guix-system-trop.in-substitutes-adad94d.x86_64-linux.iso)
+
+Built using [this](https://git.sr.ht/~abcdw/rde/commit/5dd6470437113f24cc7934f3a47f911fb768a328) simple operating-system record definition and my
+local guix checkout.
+
+To build a similiar image yourself, [add](http://guix.trop.in/en/manual/devel/en/guix.html#Specifying-Additional-Channels) rde [channel](https://trop.in/rde/manual#rde-as-a-Channel) and do:
+
+```
+guix system image -t iso9660 \
+-e '(@ (rde system install) guix-with-substitute-mirror)'
+```
+
+If you use graphical installer and network check fails, `ctrl-alt-f3`:
+
+```
+touch /tmp/installer-assume-online
+```
+
+## Guix Mirror
+
+If \*guix.gnu.org is blocked for your network by any reason[^1], you
+can use a reverse proxy, which mirrors various guix services. Please
+don't use it if the upstream services is available for you.
+
+All services are available in clearnet and yggdrasil. All services
+are exposed by **HTTP only**, if you want to have the traffic to be end to
+end encrypted use yggdrasil. The instruction about yggdrasil setup
+should appear here in some future.
+
+- **site:** [guix.trop.in](http://guix.trop.in), [guix.ygg.trop.in](http://guix.ygg.trop.in), [clearnet
+ ip](http://23.184.48.219/), [yggdrasil ip](http://[200:554d:3eb1:5bc5:6d7b:42f4:8792:efb8]/).
+- **bugtracker:** [issues.guix.trop.in](http://issues.guix.trop.in),
+ [issues.guix.ygg.trop.in](http://issues.guix.ygg.trop.in).
+- **substitutes:** [http://ci.guix.trop.in](http://ci.guix.trop.in),
+ [http://ci.guix.ygg.trop.in](http://ci.guix.ygg.trop.in), the protocol is http!
+
+It's also possible to obtain [substitutes via Tor](http://guix.trop.in/en/cookbook/en/html_node/Getting-substitutes-from-Tor.html#Getting-substitutes-from-Tor), directly from
+ci.guix.gnu.org host and there is another mirror[^2].
+
+[^1]: https://lists.gnu.org/archive/html/help-guix/2022-03/msg00004.html
+
+[^2]: http://issues.guix.trop.in/54370#2
A pages/index.html => pages/index.html +22 -0
@@ 0,0 1,22 @@
+title: main
+---
+<body>
+ <h1 class="title">trop.in</h1>
+ <p>
+Probably you are interested in yt <a href="https://youtube.com/@abcdw">channel</a>.
+ </p>
+ <p>
+rde project is <a href="./rde/ ">here</a>.
+ </p>
+ <p>
+You can find Andrew's contacts <a href="./contact">here</a>.
+ </p>
+ <a rel="me" href="https://fosstodon.org/@abcdw" hidden="hidden">Mastodon</a>
+ <h2 id="guix-mirror">Guix Mirror and Installation Image</h2>
+ <div>
+ <p>
+ <a href="./guix.html">Here</a> you can find information about guix mirror and
+link to custom installation ISO.
+ </p>
+ </div>
+</body>
A pages/posts/2023-05-10-scheme-ssgs-review.md => pages/posts/2023-05-10-scheme-ssgs-review.md +374 -0
@@ 0,0 1,374 @@
+title: Scheme Static Site Generators Review
+date: 2023-05-10 12:00
+tags: architecture, tech
+abstract: An overview of Scheme ecosystem in the field of static site generators (SSGs), review of the Haunt SSG architecture and possible ways to improve it and Guile ecosystem.
+---
+
+## Introduction
+Static site generator is a program, which accepts text files as input
+and produces static web pages as output. It can be useful in various
+scenarios: for building blog, book, documentation, project or personal
+page for example.
+
+There are a few SSGs
+[written](https://github.com/pinceladasdaweb/Static-Site-Generators#scheme)
+in Scheme available in the wild, namely
+[Haunt](https://dthompson.us/projects/haunt.html),
+[Skribilo](https://www.nongnu.org/skribilo/) and
+[Hyde](http://wiki.call-cc.org/eggref/5/hyde) and two more for Racket:
+[Pollen](https://docs.racket-lang.org/pollen/) and
+[Frog](https://docs.racket-lang.org/frog/index.html), which are
+outside of Guile ecosystem, but still quite close and can be taken as
+a source of inspiration.
+
+Hyde doesn't seem to be maintained, but the [source
+code](https://code.call-cc.org/svn/chicken-eggs/release/4/hyde/trunk/)
+still available and even [an
+attempt](https://bitbucket.org/DerGuteMoritz/ate) to go
+further/reincarnate the project exists.
+
+Skribilo is documentation production toolkit and capable of much more
+and provides a lot of functionality outside of SSG scope, so we don't
+cover it in this writing.
+
+Basically we have only one option left at the moment: Haunt and the
+further discussion will be ralated to it, but before exploring it, we
+need to get to common ground and cover the topic of different markup
+languages.
+
+## Markup Languages
+Markup languages are used for defining documentation structure,
+formatting, and relationship between its parts. They play an
+important role in SSGs, different languages can suite better for
+different tasks: simple and expressive for human convinience, powerful
+and capable for intermediate representation and manipulation,
+compatible and wide-spread for distribution.
+
+### SGML, XML, HTML, XHTML
+This is a probably most widespread family of markup languages,
+currently used all over the web. Not always, but usually SSGs create
+HTML or XHTML documents as an output. Also, it is good to know the
+relationship between those languages to understand some technical
+issues we will face later.
+
+SGML (Standard Generalized Markup Language) appeared in 1986 and
+highly influenced HTML and XML.
+
+XML (Extensible Markup Language) is a meta language, which allows to
+create new languages (like XHTML), originially developed as a
+simplification of SGML with rigid and not open for confusion syntax,
+it's defined in the SGML Doctype language. Often used for
+representing and exchange data.
+
+HTML is a more user friendly markup language, it's defined in plain
+english, has more forgiving parses and interpreters, allows things
+like uppercased tags, tags without matching closing tag. Such
+flexibilities can be convinient for users, but it makes it harder to
+programmaticaly operate on it (parse, process and serialize).
+
+XHTML (XML serialization of HTML) is a version of HTML, which is
+compliant with an XML grammar. XHTML can be used with XML parsers,
+tools for querying, transformation should work as well.
+
+While both HTML and XML are influenced by SGML, there is no direct
+relationship between them and tools for XML can't be used for HTML in
+general case.
+
+### Lightweight Markup Languages
+This is another family of markup languages, which are simplier, less
+verbose, and more human-oriented in general. The notable members are
+Wiki, Markdown, Org-mode, reStructuredText, BBCode, AsciiDoc.
+
+Often SSGs use those languages for representing the content of pages,
+posts, etc. Later it is combined with other parts and templates and
+final output is produced, usually in the form of (X)HTML documents.
+
+### Other Markup Languages
+There are a number of languages and typesetting systems, which are not
+covered by previous two sections: Texinfo, LaTeX, Skribe, Hiccup,
+SXML. The goals for them can be different: preparing hardcopies,
+using as intermediate format, or just more suitable for specific needs
+like writing documentation.
+
+## Haunt Overview
+Haunt is a simple and hackable SSG written in Scheme, it tries to
+apply functional programming ideas and the usual approach for building
+a site with it: prepare SXML page templates, read the content from
+HTML, Markdown or any other markup files and convert it to SXML,
+insert the content into templates and serialize resulting pages to
+HTML. Let's discuss various parts of this process in more details.
+
+### SXML
+SXML is a representation of XML using S-expressions: lists, symbols
+and strings, which can be less verbose than original representation
+and much easier to work with in Scheme.
+
+[SXML](https://okmij.org/ftp/Scheme/xml.html#SXML-spec) is used as
+intermediate format for pages and their parts in Haunt, which
+relatively easy to process, manipulate and later serialize to target
+formats like XHTML. It can be crafted by creating s-expression from
+Scheme code manually, or programmatically, or with a mix of both. It
+looks like this:
+
+```scheme
+(define n 3)
+
+(define slide-content
+ (get-html-part "./slide3.html" "body>div.content"))
+
+(define (sxml-slide n slide-content)
+ `((h2 ,(format #f "Slide number: ~a" n))
+ (div (@ (class "slide-content"))
+ ,slide-content
+ (p "the additional text of the slide"))))))
+```
+
+As it was mentioned in the introduction there is no direct
+relationship between XML and HTML, and while we usually can parse
+arbitrary HTML and convert it to SXML without losing significant
+information, we can't directly use XML parses for that. For example
+this HTML is not valid XML:
+
+```html
+<input type="checkbox" checked />
+```
+
+Luckily, we can present boolean attributes in full form as
+`hidden="hidden"`, which is valid both in HTML[^4] and XML.
+
+Most lightweight markup languages as well as SSGs usually targeting
+HTML, but SSG needs to combine the content, templates and data from
+various sources and merge them together, so SXML looks as a solid
+choice for intermediate representation.
+
+### The Transformation Workflow
+Each site page is built out of a series of consequently applied
+trasformations, the transformation is basically a function, which
+accepts some metadata and data and returns another data (usually SXML)
+and sometimes additional metadata. Because transformation is a basic
+pure function, a few transformations can be composed in one bigger
+transformation.
+
+We will cover it in more details in the next section, but readers,
+templates, layouts, serializers, builders are all just
+transformations. For example the top level template, called layout
+just produces SXML for the final page, which can be serialized to the
+target format. To demonstrate the workflow we will go bottom up.
+
+Let's take a simple Markdown file, where one wants to write the
+content of a blog post in human-friendly markup langugage and let's
+add a metadata to the top of this file: title, publish date, tags.
+
+```Markdown
+title: Hello, CommonMark!
+date: 2023-05-09 12:00
+tags: markdown, commonmark
+---
+
+## This is a CommonMark post
+
+CommonMark is a **strongly** defined, *highly* compatible
+specification of Markdown, learn more about CommomMark
+[here](http://commonmark.org/).
+```
+
+It can be parsed into metadata
+([alist](https://www.gnu.org/software/guile/manual/html_node/Association-Lists.html)) +
+data (SXML).
+
+```scheme
+=> ((tags "markdown" "commonmark")
+ (date . #<date nanosecond: 12 day: 9 month: 5 year: 2023 zone-offset: 14400>)
+ (title . "Hello, CommonMark!"))
+=> ((h2 "This is a CommonMark post")
+ (p "CommonMark is a " (strong "strongly") " defined, "
+ (em "highly") " compatible" "\n"
+ "specification of Markdown, learn more about CommomMark" "\n"
+ (a (@ (href "http://commonmark.org/")) "here") "."))
+```
+
+Metadata+data representing one post is a good unit of operation. With
+one more transformation (it can be just a template, function adding
+`html`, `head`, `body` tags and a few more minor things) SSG can
+produce almost ready for serialization SXML. Decide on resulting file
+name, one more serialization step and final HTML is here.
+
+Some additional transformation can be desirable in between: substitute
+relative links to source markup files to finally generated html files
+or something else, but overall it fits this general trasformation
+workflow well.
+
+Let's zoom out a little and take a look at the directory, rather than
+a single file. Usually, SSGs operate on a number of files and in
+addition to simple pages can generate composite pages like a list of
+articles, rss feeds or something else. For this purpose our unit of
+operation becomes a list of data+metadata objects: instead of parsing
+one markup file SSG traverses the whole directory and generates a list
+of objects for future transformation, overall idea still the same, but
+instead many output files for many input files, SSG produces a list
+containing only a few or even one output file.
+
+### The Implementation
+
+#### The Entry Point
+The entry point is a `site` record, which can be created with a
+function having the following docstring:
+
+```
+Create a new site object. All arguments are optional:
+
+TITLE: The name of the site
+DOMAIN: The domain that will host the site
+SCHEME: Either 'https' or 'http' ('https' by default)
+POSTS-DIRECTORY: The directory where posts are found
+FILE-FILTER: A predicate procedure that returns #f when a post file
+should be ignored, and #f otherwise. Emacs temp files are ignored by
+default.
+BUILD-DIRECTORY: The directory that generated pages are stored in
+DEFAULT-METADATA: An alist of arbitrary default metadata for posts
+whose keys are symbols
+MAKE-SLUG: A procedure generating a file name slug from a post
+READERS: A list of reader objects for processing posts
+BUILDERS: A list of procedures for building pages from posts
+```
+
+The primary thing here is a list of builders, as previously mentioned
+a builder is a special case of complex transformation, it's a thing,
+which do all the work including parsing, templating, generating
+collections, serialization, etc.
+
+The rest of the list is basically metadata or auxiliary functions,
+while many of those values can be useful, almost none of them are
+needed in many cases. `scheme` and `domain` used for rss/atom feeds,
+which are rare for personal or landing pages, the similiar logic is
+applicable for the rest of function arguments, except maybe
+`build-directory`, which almost always make sense.
+
+Providing default values for them is convinient, but making them to be
+fields of `site` records incorporates unecessary assumptions about
+blog nature of the site, which can negatively impact the rest of the
+implementation by adding unwanted coupling and reducing composability.
+
+TODO: Write about possible alternative for site fields.
+
+#### Builders
+Builders are functions, which accept `site` and `posts` and returns a
+list of artifacts. Artifacts are records, which have
+`artifact-writer` field, containing a closure writing actual output
+file. There are a number of different builders provided out of the
+box, but the most basic one (static-page) is missing, luckily it's not
+hard to implement it, so let's do it.
+
+```scheme
+(define* (page-theme #:key (footer %default-footer))
+ (theme
+ #:layout
+ (lambda (site title body)
+ `((doctype "html")
+ (head
+ (meta (@ (charset "utf-8")))
+ (title ,(string-append title " — " (site-title site))))
+ (body
+ (div (@ (class "container"))
+ ,body
+ ,footer))))
+ #:post-template
+ (lambda (post)
+ `((div ,(post-sxml post))))))
+
+(define* (static-page file destination
+ #:key
+ (theme (page-theme))
+ (reader commonmark-reader))
+ "Return a builder procedure that reads FILE into SXML, adjusts it
+according to the THEME and serialize to HTML and put it to
+build-directory of the site. DESTINATION is a relative resulting file
+path."
+ (lambda (site posts)
+ (list
+ (serialized-artifact
+ destination
+ (render-post theme site (read-post reader file '()))
+ sxml->html))))
+```
+
+As described in a section about transformations, the series of
+transmorations happens here:
+- `read-post` basically prases markdown and returns SXML + metadata.
+- `render-post` uses post-template from `theme` to produce SXML post body.
+- `render-post` uses layout from `theme` to produce SXML post body.
+- `serialized-artifact` creates a closure, which wraps `sxml->html`
+ and will later serialize obtained SXML for the page to HTML.
+
+### Readers
+There is a concept of readers, small functions
+
+
+### Guile-Commonmark
+It used in haunt by default to parse markdown files in SXML, it
+doesn't support embeded html, tables, footnotes and comments, so it
+can be quite inconvinient for many use cases.
+
+TODO: It was something else important that was missing in
+guile-commonmark?
+
+### Mix of imlicit and explicit things
+
+### Metadata
+Accepts only one-line metadata. Doesn't accept files without metadata.
+Metadata is not a part of the html grammar -> post is not a valid html.
+
+register-metadata-parser! is a reimplementation of multimethods.
+
+
+### Site Alist
+
+```
+`((posts-directory . "pages/posts")
+ (build-directory . "target/site"))
+```
+
+### Theme
+Layout for posts and collections is the same. the same layout is
+coupled to both of them.
+
+### TODOs
+Linking to md files are not converted to apropriate urls, do we want
+to implement it and if want then how?
+
+Org-roam workflow
+
+### Workflows
+- ox-haunt
+- md
+- citations
+- one file multiple post
+
+### Build/Deploy
+Rebuild and redeploy do it for the whole site every time.
+
+
+TODO:
+
+How to build page with links to rss?
+How to build a collection with different template?
+
+## Conclusion
+The conclusion here
+
+### Future Work
+Possible future steps are improving SXML/HTML ecosystem in Guile,
+producing tree-sitter based parsers for various formats
+
+
+**Aknowledgments.** Thank you to [David
+Thompson](https://dthompson.us/about.html) for making Haunt.
+
+
+[^1]: https://jamstack.org/generators/haunt/
+
+[^2]: https://github.com/pinceladasdaweb/Static-Site-Generators#scheme
+
+[^3]: https://stackoverflow.com/questions/1429065/compare-contrast-html-xhtml-xml-and-html5
+
+[^4]: https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML
A pages/rde/index.md => pages/rde/index.md +16 -0
@@ 0,0 1,16 @@
+title: trop.in/rde
+---
+# trop.in/rde
+
+Developers and power user friendly GNU/Linux distribution.
+
+Build [status](https://builds.sr.ht/~abcdw/rde?).
+
+The documentation: [manual](/rde/manual).
+
+The source code: [sr.ht](https://git.sr.ht/~abcdw/rde),
+[github](https://github.com/abcdw/rde) (mirror).
+
+There is a [video](https://youtu.be/6yrYWjjuIOs) about rde.
+
+[Contact](/contact) the author for more details.
A pages/sport.md => pages/sport.md +24 -0
@@ 0,0 1,24 @@
+title: sport
+---
+# Sport
+
+This page is related to trop.in/sport [chat](https://t.me/joinchat/PEtuyKqvlsQ3NzJi), where different
+activities, workouts and events are organized:
+
+- Climbing workouts.
+- Kayking workouts.
+- Wakeboard camps.
+- Snowboard trips.
+- And some others.
+
+If you want to participate, join the chat or [contact](contact) Andrew via email
+or any other way.
+
+## Climbing
+
+- **[Belay Masterclass](https://www.youtube.com/playlist?list=PL5FEOhiQGSo8PBwTZPeiwQGcxQ0xB99Gt):** a series of videos, all about belaying: ropes,
+ carabiners, harness, quickdraws and of course techniques.
+- **[Response to Belay Masterclass Ep. 6](https://youtu.be/H63pxyXHP50):** explanation of different
+ belaying techniques, including PBUS (the one usually we use in our
+ club).
+- **[How to Tie Figure 8](https://youtu.be/PJkCaUUhqgs):** a tutorial on Figure 8 knot.
A pages/stream.html => pages/stream.html +16 -0
@@ 0,0 1,16 @@
+title: stream
+plain: #t
+---
+<body>
+<div id="content" class="content">
+<h1 class="title" align="center">trop.in/stream</h1>
+<p>
+ Hi! I'm Andrew Tropin and I stream from time to time. You can find recordings of the streams at
+ <a href="https://diode.zone/c/andrewtropin/videos">peertube</a> and
+ <a href="https://youtube.com/@abcdw">youtube</a>.
+</p>
+<!-- <p><code>mpv https://diode.zone/w/uwH9rPkGLGesfp2GCd7sHT</code></p> -->
+<iframe width="800" height="450" src="https://diode.zone/videos/embed/e7098d6e-0314-4ff2-835f-d01bab54dad5" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe>
+<iframe src="https://web.libera.chat/gamja/?nick=guest#tropin" style="border:0; height:450px; width:400px"></iframe>
+</div>
+</body>