Compare commits
3 Commits
configurin
...
books
Author | SHA1 | Date | |
---|---|---|---|
2e9a9155f8 | |||
1ab9c3af46 | |||
b93aab5742 |
2
attributions.md
Normal file
2
attributions.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
- Book by rivercon from the Noun Project
|
||||||
|
- [Git logo](https://git-scm.com/downloads/logos) by Jason Long
|
7
books.xml
Normal file
7
books.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<books>
|
||||||
|
<book>
|
||||||
|
<date>2019-05-28</date>
|
||||||
|
<title>Uppo-Nallen talviturkki</title>
|
||||||
|
<status>read</status>
|
||||||
|
</book>
|
||||||
|
</books>
|
5
books/2014-07-10-pandoras-star.md
Normal file
5
books/2014-07-10-pandoras-star.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Uppo-Nalle ja Nukku-Ukko
|
||||||
|
status: reading
|
||||||
|
---
|
||||||
|
|
4
books/2016-11-04-the-fractal-prince.md
Normal file
4
books/2016-11-04-the-fractal-prince.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: The Fractal Prince
|
||||||
|
status: reading
|
||||||
|
---
|
4
books/2019-05-28-nukku-ukko.md
Normal file
4
books/2019-05-28-nukku-ukko.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: Uppo-Nalle ja Nukku-Ukko
|
||||||
|
status: reading
|
||||||
|
---
|
5
books/2019-05-28-upponallen-talviturkki.md
Normal file
5
books/2019-05-28-upponallen-talviturkki.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Uppo-Nallen talviturkki
|
||||||
|
status: read
|
||||||
|
---
|
||||||
|
|
@ -51,6 +51,15 @@ article .header {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 2.4rem;
|
||||||
|
height: 2.4rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-self: center;
|
||||||
|
top: .40em;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 319px) {
|
@media (max-width: 319px) {
|
||||||
body {
|
body {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
@ -111,7 +120,7 @@ article .header {
|
|||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
body {
|
body {
|
||||||
width: 85rem;
|
width: 60rem;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,6 @@
|
|||||||
/* Generated by pandoc. */
|
/* Generated by pandoc. */
|
||||||
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre.sourceCode
|
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
|
||||||
{
|
{ margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
/* border: 0; */
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
pre.sourceCode
|
|
||||||
{
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
background-color: rgb(238,238,255);
|
|
||||||
padding: 10px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
|
td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
|
||||||
td.sourceCode { padding-left: 5px; }
|
td.sourceCode { padding-left: 5px; }
|
||||||
.sourceCode span.kw { color: #007020; font-weight: bold; }
|
.sourceCode span.kw { color: #007020; font-weight: bold; }
|
||||||
|
1
images/book_read.svg
Normal file
1
images/book_read.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="read" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 56 70" style="enable-background:new 0 0 56 56;" xml:space="preserve"><path d="M48.2026367,4.003418c0-0.5522461-0.4477539-1-1-1H17.7766724C17.7706909,3.0032959,17.7657471,3,17.7597656,3 s-0.0109253,0.0032959-0.0169067,0.003418h-4.8380737c-2.8188477,0-5.1118164,2.4799805-5.1118164,5.5288086v38.4257812 c0,0.0093994,0.005127,0.0172119,0.0053711,0.0265503C7.8088379,50.3031616,10.303833,53,13.3701172,53h33.8369141 c0.3862305,0,0.737793-0.2226562,0.9033203-0.5712891c0.1655273-0.3491211,0.1152344-0.762207-0.1289062-1.0615234 c-2.0512695-2.5102539-2.0512695-6.296875,0-8.8071289c0.2003784-0.2456665,0.262085-0.5665894,0.1891479-0.8672485 c0.0089111-0.053772,0.0320435-0.102356,0.0320435-0.1586304V4.003418z M46.2026367,40.9272461H18.7597656V5.003418h27.4428711 V40.9272461z M12.9047852,5.003418h3.8549805v35.9238281h-3.3896484c-1.3610229,0-2.6083374,0.5328979-3.5771484,1.4140625 V8.5322266C9.7929688,6.5864258,11.1889648,5.003418,12.9047852,5.003418z M45.3833008,51H13.3701172 c-1.9702148,0-3.5727539-1.8105469-3.5727539-4.0361328s1.6025391-4.0366211,3.5727539-4.0366211h32.0131836 C44.1420898,45.4414062,44.1420898,48.4858398,45.3833008,51z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
images/book_reading.svg
Normal file
1
images/book_reading.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 6.8 KiB |
@ -19,8 +19,8 @@ My [GPG key](./resources/2104943D6033C.txt)
|
|||||||
- Working on an internal Haskell based tool at Relex Oy
|
- Working on an internal Haskell based tool at Relex Oy
|
||||||
- Some contributions to [darcshub](https://hub.darcs.net/)
|
- Some contributions to [darcshub](https://hub.darcs.net/)
|
||||||
- Some contributions to [xmonad](https://github.com/xmonad)
|
- Some contributions to [xmonad](https://github.com/xmonad)
|
||||||
- Dozens of personal projects, most of which ended up being just tests for
|
- My [Github profile](https://github.com/MasseR)
|
||||||
different libraries, techniques or algorithms.
|
- My [Gitea profile](https://git.rauhala.info/MasseR)
|
||||||
- **Systems integrations**
|
- **Systems integrations**
|
||||||
- Working as a consultant from Avoltus Oy to different companies using
|
- Working as a consultant from Avoltus Oy to different companies using
|
||||||
[Mulesoft](https://developer.mulesoft.com/). Systems include webshops,
|
[Mulesoft](https://developer.mulesoft.com/). Systems include webshops,
|
||||||
|
22
js/api.js
22
js/api.js
@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
var getApiIpfsCurrent = function(onSuccess, onError) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.open('GET', '/api/ipfs/current', true);
|
|
||||||
xhr.setRequestHeader('Accept', 'application/json');
|
|
||||||
xhr.onreadystatechange = function () {
|
|
||||||
var res = null;
|
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
if (xhr.status === 204 || xhr.status === 205) {
|
|
||||||
onSuccess();
|
|
||||||
} else if (xhr.status >= 200 && xhr.status < 300) {
|
|
||||||
try { res = JSON.parse(xhr.responseText); } catch (e) { onError(e); }
|
|
||||||
if (res) onSuccess(res);
|
|
||||||
} else {
|
|
||||||
try { res = JSON.parse(xhr.responseText); } catch (e) { onError(e); }
|
|
||||||
if (res) onError(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send(null);
|
|
||||||
};
|
|
||||||
|
|
10
js/app.js
10
js/app.js
@ -1,10 +0,0 @@
|
|||||||
$(document).ready(function() {
|
|
||||||
var success = function(x) {
|
|
||||||
$("#ipfs > em").html(x);
|
|
||||||
};
|
|
||||||
var error = function(x) {
|
|
||||||
$("#ipfs").hide();
|
|
||||||
console.log("ipfs hash not found: " + x);
|
|
||||||
};
|
|
||||||
getApiIpfsCurrent(success, error);
|
|
||||||
});
|
|
2
js/jquery-3.3.1.min.js
vendored
2
js/jquery-3.3.1.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,78 +0,0 @@
|
|||||||
---
|
|
||||||
title: Extensible configuration Pt. 1
|
|
||||||
date: 2019-03-27
|
|
||||||
---
|
|
||||||
|
|
||||||
This is the first part of a series where I'm going through how to make
|
|
||||||
extensible configuration. There is nothing groundbreaking or new in this
|
|
||||||
series, it's just me going through different implementations and trying to
|
|
||||||
understand them.
|
|
||||||
|
|
||||||
The source material for this post is [the fixed point implementation](https://github.com/NixOS/nixpkgs/blob/master/lib/fixed-points.nix) for nix.
|
|
||||||
|
|
||||||
By extensible configuration, I'm talking about nix style extensible
|
|
||||||
configuration, like overlays, overrides and extensions. Let's see an example of
|
|
||||||
an extensible configuration.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
{ haskellPackages, fetchFromGitHub }:
|
|
||||||
|
|
||||||
let
|
|
||||||
purescript = fetchFromGitHub {
|
|
||||||
owner = "purescript";
|
|
||||||
repo = "purescript";
|
|
||||||
rev = "2cb4a6496052db726e099539be682b87585af494";
|
|
||||||
sha256 = "1v4gs08xnqgym6jj3drkzbic7ln3hfmflpbpij3qzwxsmqd2abr7";
|
|
||||||
}
|
|
||||||
hp = haskellPackages.extend (self: super: {
|
|
||||||
purescript = super.callCabal2nix "purescript" purescript {};
|
|
||||||
});
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
hp.purescript;
|
|
||||||
```
|
|
||||||
|
|
||||||
On a high level we are augmenting the `haskellPackages` attrset by replacing
|
|
||||||
the existing purescript package with a different one. The extension is a
|
|
||||||
function that takes two arguments, `self` and `super`. `super` is the original
|
|
||||||
non-lazy value and `self` is the lazy value that corresponds to the value at
|
|
||||||
end.
|
|
||||||
|
|
||||||
The first step on this journey is done by getting to know `fix`. Fix is
|
|
||||||
described being the least fixed point of a function. In practice it's a
|
|
||||||
function allowing declaring recursive functions without explicit recursion.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
fix = f: let x = f x; in x
|
|
||||||
```
|
|
||||||
|
|
||||||
With fix you can have access to the lazy `self` value. It's value is whatever
|
|
||||||
would have been computed in the end. As it is lazy, it is possible to end up in
|
|
||||||
a recursive loop if there is a cyclic dependency.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
let recursive = fix (self: {
|
|
||||||
foo = 3;
|
|
||||||
bar = self.foo + 1;
|
|
||||||
});
|
|
||||||
infinite = fix (self: {
|
|
||||||
foo = self.bar + 1;
|
|
||||||
bar = self.foo + 1;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
You can try those yourself. The first version is fine and returns an attrset
|
|
||||||
like you would expect. The second one has a cyclic dependency and nix helpfully
|
|
||||||
errors out.
|
|
||||||
|
|
||||||
The next step is making a function that has access to the unmodified original
|
|
||||||
values. This is managed through the `extends` function. It took a while for me to understand what's happening in there, but luckily nix has [good documentation](https://github.com/NixOS/nixpkgs/blob/67b1265fb3d38ead5a57fee838405a2d997777c2/lib/fixed-points.nix#L37-L65) for it.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
extends = f: rattrs: self: let super = rattrs self; in super // f self super
|
|
||||||
```
|
|
||||||
|
|
||||||
- https://elvishjerricco.github.io/2017/04/01/nix-style-configs-in-haskell.html
|
|
||||||
- https://github.com/NixOS/nixpkgs/blob/master/lib/fixed-points.nix
|
|
||||||
- https://chshersh.github.io/posts/2019-03-25-comonadic-builders
|
|
@ -6,10 +6,11 @@ let
|
|||||||
shell = pkgs.buildEnv {
|
shell = pkgs.buildEnv {
|
||||||
name = "site-shell";
|
name = "site-shell";
|
||||||
paths = [];
|
paths = [];
|
||||||
buildInputs = [
|
buildInputs = with haskellPackages; [
|
||||||
haskellPackages.ghcid
|
ghcid
|
||||||
haskellPackages.hasktags
|
hasktags
|
||||||
(haskellPackages.ghcWithHoogle (h: site.buildInputs ++ site.propagatedBuildInputs))
|
cabal-install
|
||||||
|
(ghcWithHoogle (h: site.buildInputs ++ site.propagatedBuildInputs))
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,5 +12,8 @@ executable site
|
|||||||
build-depends: base == 4.*
|
build-depends: base == 4.*
|
||||||
, hakyll >= 4.10
|
, hakyll >= 4.10
|
||||||
, time
|
, time
|
||||||
|
, xml-conduit
|
||||||
|
, xml-lens
|
||||||
|
, lens
|
||||||
ghc-options: -threaded
|
ghc-options: -threaded
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
57
site.hs
57
site.hs
@ -1,8 +1,14 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
import Data.List (sortOn)
|
import Data.Monoid (mappend)
|
||||||
import Data.Time (defaultTimeLocale, formatTime)
|
|
||||||
import Hakyll
|
import Hakyll
|
||||||
|
import Data.List (sortBy, sortOn)
|
||||||
|
import Data.Time (formatTime, defaultTimeLocale)
|
||||||
|
|
||||||
|
data Book =
|
||||||
|
Book { title :: String
|
||||||
|
, date :: Day
|
||||||
|
, status :: String }
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
@ -29,20 +35,53 @@ main = hakyllWith defaultConfiguration{ deployCommand = "ipfs add -Q -r _site" }
|
|||||||
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
||||||
>>= relativizeUrls
|
>>= relativizeUrls
|
||||||
|
|
||||||
match "posts/*" $ do
|
match "books/*" $ do
|
||||||
route $ setExtension "html"
|
route $ setExtension "html"
|
||||||
compile $ pandocCompiler
|
compile $ pandocCompiler
|
||||||
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
||||||
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
||||||
>>= relativizeUrls
|
>>= relativizeUrls
|
||||||
|
|
||||||
create ["posts.html"] $ do
|
match "posts/incomplete/*" $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
match "posts/guides/*" $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
match "posts/brainstorming/*" $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
create ["books.html"] $ do
|
||||||
route idRoute
|
route idRoute
|
||||||
compile $ do
|
compile $ do
|
||||||
posts <- modFirst =<< loadAll "posts/*"
|
books <- reverse <$> loadAll "books/*"
|
||||||
|
let ctx = listField "books" postCtx (pure books) <>
|
||||||
|
constField "title" "Books" <>
|
||||||
|
defaultContext
|
||||||
|
makeItem ""
|
||||||
|
>>= loadAndApplyTemplate "templates/books.html" ctx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" ctx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
create ["guides.html"] $ do
|
||||||
|
route idRoute
|
||||||
|
compile $ do
|
||||||
|
posts <- modFirst =<< loadAll "posts/guides/*"
|
||||||
let archiveCtx =
|
let archiveCtx =
|
||||||
listField "posts" postCtx (return posts) <>
|
listField "posts" postCtx (return posts) `mappend`
|
||||||
constField "title" "Posts" <>
|
constField "title" "Guides" `mappend`
|
||||||
defaultContext
|
defaultContext
|
||||||
|
|
||||||
makeItem ""
|
makeItem ""
|
||||||
@ -62,8 +101,8 @@ modFirst = fmap reverse . modified
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
postCtx :: Context String
|
postCtx :: Context String
|
||||||
postCtx =
|
postCtx =
|
||||||
dateField "date" "%B %e, %Y" <>
|
dateField "date" "%B %e, %Y" `mappend`
|
||||||
modifiedField "modified" "%B %e, %Y" <>
|
modifiedField "modified" "%B %e, %Y" `mappend`
|
||||||
defaultContext
|
defaultContext
|
||||||
where
|
where
|
||||||
modifiedField key format = field key $ \i -> do
|
modifiedField key format = field key $ \i -> do
|
||||||
|
9
templates/books.html
Normal file
9
templates/books.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
A collection of books I have read lately.
|
||||||
|
|
||||||
|
<ul class="books">
|
||||||
|
$for(books)$
|
||||||
|
<li>
|
||||||
|
<img src="/images/book_$status$.svg" class="icon" /><a href="$url$">$title$</a> - $date$
|
||||||
|
</li>
|
||||||
|
$endfor$
|
||||||
|
</ul>
|
@ -18,7 +18,6 @@
|
|||||||
<!-- Logo by Jason Long -->
|
<!-- Logo by Jason Long -->
|
||||||
<a href="https://git.rauhala.info"><img src="/images/git_16.png" alt="git" /></a>
|
<a href="https://git.rauhala.info"><img src="/images/git_16.png" alt="git" /></a>
|
||||||
<a href="/contact.html">Contact</a>
|
<a href="/contact.html">Contact</a>
|
||||||
<a href="/posts.html">Posts</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@ -29,11 +28,7 @@
|
|||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
Site proudly generated by
|
Site proudly generated by
|
||||||
<a href="http://jaspervdj.be/hakyll">Hakyll</a>
|
<a href="http://jaspervdj.be/hakyll">Hakyll</a><br />
|
||||||
<span id="ipfs">and found on IPFS as <em></em></ipfs>
|
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
<script type="application/javascript" src="/js/jquery-3.3.1.min.js"></script>
|
|
||||||
<script type="application/javascript" src="/js/api.js"></script>
|
|
||||||
<script type="application/javascript" src="/js/app.js"></script>
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
Me writing out interesting ideas and experiments.
|
A list of small and big guides.
|
||||||
|
|
||||||
$partial("templates/post-list.html")$
|
$partial("templates/post-list.html")$
|
||||||
|
Reference in New Issue
Block a user