aboutsummaryrefslogtreecommitdiff
path: root/v2/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xv2/src/bin/categories2
-rwxr-xr-xv2/src/bin/category2
-rwxr-xr-xv2/src/bin/coll2path88
-rwxr-xr-xv2/src/bin/collection-for29
-rwxr-xr-xv2/src/bin/collections4
-rwxr-xr-xv2/src/bin/conf2
-rwxr-xr-xv2/src/bin/feed9
-rwxr-xr-xv2/src/bin/html10
-rwxr-xr-xv2/src/bin/index8
-rwxr-xr-xv2/src/bin/indexentry4
-rwxr-xr-xv2/src/bin/makemake47
-rwxr-xr-xv2/src/bin/xmlentry8
-rw-r--r--v2/src/content/en/about.page (renamed from v2/src/content/en/about.md)0
-rw-r--r--v2/src/content/en/pastebin/raku-tuple-type-annotation.md (renamed from v2/src/content/en/pastebins/raku-tuple-type-annotation.md)0
-rw-r--r--v2/src/content/en/pastebin/sicp-exercise-3-19.md (renamed from v2/src/content/en/pastebins/sicp-exercise-3-19.md)0
-rw-r--r--v2/src/content/en/remembering-ann.md186
-rw-r--r--v2/src/content/en/til/lisp-three-way-conditional.md (renamed from v2/src/content/en/tils/lisp-three-way-conditional.md)0
-rw-r--r--v2/src/content/pt/hea/condicional-ternario-lisp.md65
-rw-r--r--v2/src/content/pt/pastebin/exercicios-sicp-e-19.md (renamed from v2/src/content/pt/pastebins/exercicios-sicp-e-19.md)0
-rw-r--r--v2/src/content/pt/sobre.page (renamed from v2/src/content/pt/sobre.md)0
-rw-r--r--v2/src/lib/base.en.conf39
-rw-r--r--v2/src/lib/base.pt.conf39
-rw-r--r--v2/src/lib/commencement.en.conf7
-rw-r--r--v2/src/lib/commencement.pt.conf7
24 files changed, 478 insertions, 78 deletions
diff --git a/v2/src/bin/categories b/v2/src/bin/categories
index bc08704..de65acb 100755
--- a/v2/src/bin/categories
+++ b/v2/src/bin/categories
@@ -24,7 +24,7 @@ help() {
Generate the index.categories entry for english pastebins:
- $ categories src/en/pastebins/index.categories
+ $ categories src/en/pastebin/index.categories
EOF
}
diff --git a/v2/src/bin/category b/v2/src/bin/category
index 2a2fdea..16eea0e 100755
--- a/v2/src/bin/category
+++ b/v2/src/bin/category
@@ -68,7 +68,7 @@ eval "$(assert_arg "$FILENAME" 'FILENAME')"
# shellcheck source=/dev/null
-. "${FILENAME%.md}.conf"
+. "${FILENAME%.*}.conf"
DIR="$(dirname "$FILENAME")"
diff --git a/v2/src/bin/coll2path b/v2/src/bin/coll2path
new file mode 100755
index 0000000..79b2f53
--- /dev/null
+++ b/v2/src/bin/coll2path
@@ -0,0 +1,88 @@
+#!/bin/sh
+set -eu
+
+usage() {
+ cat <<-'EOF'
+ Usage:
+ coll2path LANGUAGE COLLECTION
+ coll2path -h
+ EOF
+}
+
+help() {
+ cat <<-'EOF'
+
+
+ Options:
+ -h, --help show this message
+
+ LANGUAGE in which language to list the collections
+ names for
+ COLLECTION what collection to get the path for
+
+
+ Get the path for the COLLECTION, doing the proper translation
+ on the way, and checking if is "article".
+
+
+ Examples:
+
+ Get the path for "TIL" in portuguese:
+
+ $ coll2path pt til
+ hea/
+
+
+ Get the path for "articles" in english
+
+ $ collections en articles
+
+ EOF
+}
+
+
+for flag in "$@"; do
+ case "$flag" in
+ --)
+ break
+ ;;
+ --help)
+ usage
+ help
+ exit
+ ;;
+ *)
+ ;;
+ esac
+done
+
+while getopts 'h' flag; do
+ case "$flag" in
+ h)
+ usage
+ help
+ exit
+ ;;
+ *)
+ usage >&2
+ exit 2
+ esac
+done
+shift $((OPTIND - 1))
+
+. src/lib.sh
+
+
+LANGUAGE="${1:-}"
+COLLECTION="${2:-}"
+eval "$(assert_arg "$LANGUAGE" 'LANGUAGE')"
+
+# shellcheck source=/dev/null
+. src/lib/commencement."$LANGUAGE".conf
+
+if [ -z "$COLLECTION" ]; then
+ echo "${article_collection_name:-}"
+else
+ NAME="$(eval "echo \"\$${COLLECTION}_collection_name\"")"
+ echo "$NAME${NAME:+/}"
+fi
diff --git a/v2/src/bin/collection-for b/v2/src/bin/collection-for
index b3fc211..87f1204 100755
--- a/v2/src/bin/collection-for
+++ b/v2/src/bin/collection-for
@@ -24,10 +24,10 @@ help() {
Examples:
- Get "tils" for "src/en/tils/some-pt.md":
+ Get "til" for "src/en/til/some-pt.md":
- $ collection-for src/en/tils/some-pt.md
- tils
+ $ collection-for src/en/til/some-pt.md
+ til
EOF
}
@@ -69,15 +69,18 @@ FILE="${1:-}"
eval "$(assert_arg "$FILE" 'FILE')"
-# echo "${FILE#"$CONTENT_PREFIX"/}" | cut -d/ -f1
-# echo "${FILE#"$CONTENT_PREFIX"/}" | awk '{
- # awk -F/ '$3 && $0=$2 { print; next } $0'
-
-ATTEMPT="$(echo "${FILE#"$CONTENT_PREFIX"/}" | cut -d/ -f2-)"
-
-if [ "$ATTEMPT" = 'index.html' ]; then
- echo articles
+lang="$(lang-for "$FILE")"
+DIR="$(dirname "$FILE")"
+if [ "$DIR" = "$CONTENT_PREFIX/$lang" ]; then
+ echo
else
- NAME="$(echo "$ATTEMPT" | cut -d/ -f1)"
- collections | grep "$NAME"
+ NAME="$(basename "$DIR")"
+ NTH="$(
+ collections |
+ xargs -I% coll2path "$lang" % |
+ awk '{ print NR, substr($0, 1, length($0) - 1) }' |
+ grep " $NAME$" |
+ cut -d' ' -f1
+ )"
+ collections | awk -vNTH="$NTH" 'NR == NTH'
fi
diff --git a/v2/src/bin/collections b/v2/src/bin/collections
index 1df0c39..0a8e156 100755
--- a/v2/src/bin/collections
+++ b/v2/src/bin/collections
@@ -28,8 +28,8 @@ help() {
Just run it:
$ collections
- tils
- pastebins
+ til
+ pastebin
EOF
}
diff --git a/v2/src/bin/conf b/v2/src/bin/conf
index 62ef97a..92ecc68 100755
--- a/v2/src/bin/conf
+++ b/v2/src/bin/conf
@@ -178,7 +178,7 @@ if [ -n "${update:-}" ]; then
fi
-url_part="$(printf '%s' "${FILENAME%.md}.html" | sed "s|^$CONTENT_PREFIX/||")"
+url_part="$(printf '%s' "${FILENAME%.*}.html" | sed "s|^$CONTENT_PREFIX/||")"
url="$(url-for "$url_part")"
title_uri="$(uri "$title")"
diff --git a/v2/src/bin/feed b/v2/src/bin/feed
index 52c6199..f55ba89 100755
--- a/v2/src/bin/feed
+++ b/v2/src/bin/feed
@@ -27,7 +27,7 @@ help() {
Generate a feed for TILs:
- $ feed src/en/tils/feed.xml
+ $ feed src/en/til/feed.xml
EOF
}
@@ -76,8 +76,9 @@ eval "$(assert_arg "$FILENAME" 'FILENAME')"
now="$(date -uIs)"
url_absolute="$(url-for "${FILENAME#"$CONTENT_PREFIX"/}" | absolute)"
site_name_html="$(htmlesc "${site_name:?}")"
-collection="$(collection-for "$FILENAME")"
-collection_url_absolute="$(url-for "${lang:?}/$collection/" | absolute)"
+collection="$(sh src/bin/collection-for "$FILENAME")"
+coll_path="$(coll2path "${lang:?}" "$collection")"
+collection_url_absolute="$(url-for "${lang:?}/$coll_path" | absolute)"
feed_title_html="$(eval "echo \"\$feed_${collection}_title\"" | htmlesc)"
export now url_absolute site_name_html collection_url_absolute feed_title_html
@@ -96,7 +97,7 @@ mkdir -p "$DIR"
printf '' > "$DIR"/index.extrafeeds
while read -r category; do
url_absolute="$(url-for "${DIR#"$CONTENT_PREFIX"/}/feed.$category.xml" | absolute)"
- collection_url_absolute="$(url-for "${DIR#"$CONTENT_PREFIX"/}/${by_category_url_part:?}#$category" | absolute)"
+ collection_url_absolute="$(url-for "${DIR#"$CONTENT_PREFIX"/}/${by_category_url_name:?}#$category" | absolute)"
feed_title_html="$(eval "echo \"\$index_category_${collection}_title\"" | htmlesc)"
export url_absolute collection_url_absolute feed_title_html
diff --git a/v2/src/bin/html b/v2/src/bin/html
index f995753..578c539 100755
--- a/v2/src/bin/html
+++ b/v2/src/bin/html
@@ -68,7 +68,7 @@ eval "$(assert_arg "$FILENAME" 'FILENAME')"
# shellcheck source=/dev/null
-. "${FILENAME%.md}.conf"
+. "${FILENAME%.*}.conf"
#
# Utility functions
@@ -99,7 +99,7 @@ markdown_to_html() {
}
extract_plaintext_snippets() (
- SNIPPETS="${FILENAME%.md}.snippets"
+ SNIPPETS="${FILENAME%.*}.snippets"
printf '' > "$SNIPPETS"
F="$(mkstemp)"
cat > "$F"
@@ -117,7 +117,7 @@ extract_plaintext_snippets() (
if printf '%s' "$line" | grep -q "^$INDENT<pre><code"; then
IN_BLOCK=1
- OUT="${FILENAME%.md}.html.$BLOCK_NUMBER.txt"
+ OUT="${FILENAME%.*}.html.$BLOCK_NUMBER.txt"
BLOCK_NUMBER=$((BLOCK_NUMBER + 1))
printf '%s\n' "$line" |
sed "s|^\($INDENT<pre><code.*>\)\(.*\)$|\2|" |
@@ -205,7 +205,7 @@ warn_duplicate_ids() {
}
emit_body() {
- < "${FILENAME%.md}.content" \
+ < "${FILENAME%.*}.content" \
markdown_to_html |
extract_plaintext_snippets |
add_line_numbers |
@@ -214,5 +214,5 @@ emit_body() {
}
envsubst < src/lib/preamble.html
-emit_body | tee "${FILENAME%.md}.htmlbody"
+emit_body | tee "${FILENAME%.*}.htmlbody"
envsubst < src/lib/postamble.html
diff --git a/v2/src/bin/index b/v2/src/bin/index
index 36750b3..46e0c88 100755
--- a/v2/src/bin/index
+++ b/v2/src/bin/index
@@ -4,8 +4,8 @@ set -eu
usage() {
cat <<-'EOF'
Usage:
- collection FILENAME
- collection -h
+ index FILENAME
+ index -h
EOF
}
@@ -25,7 +25,7 @@ help() {
Generate an index.html entry for english pastebins:
- $ collection src/en/pastebins/index.html
+ $ index src/en/pastebin/index.html
EOF
}
@@ -79,7 +79,7 @@ url_part="$(printf '%s' "${FILENAME#"$CONTENT_PREFIX"/}" | sed "s|\.md$|.html|")
url_absolute="$(url-for "$url_part" | absolute)"
collection="$(collection-for "$FILENAME")"
feed_url="$(url-for "${DIR#"$CONTENT_PREFIX"/}"/feed.xml)"
-by_category_url="$(url-for "${DIR#"$CONTENT_PREFIX"/}/${by_category_url_part:?}")"
+by_category_url="$(url-for "${DIR#"$CONTENT_PREFIX"/}/${by_category_url_name:?}")"
title_html="$(eval "echo \"\$index_${collection}_title\"" | htmlesc)"
index_recent_title_html="$(eval "echo \"\$index_recent_${collection}_title\"" | htmlesc)"
index_category_title_html="$(eval "echo \"\$index_category_${collection}_title\"" | htmlesc)"
diff --git a/v2/src/bin/indexentry b/v2/src/bin/indexentry
index 03bf771..f971a30 100755
--- a/v2/src/bin/indexentry
+++ b/v2/src/bin/indexentry
@@ -26,7 +26,7 @@ help() {
Generate the index entry for a TIL:
- $ indexentry src/tils/a-til.md > src/tils/a-til.indexentry
+ $ indexentry src/til/a-til.md > src/til/a-til.indexentry
EOF
}
@@ -68,6 +68,6 @@ eval "$(assert_arg "$FILENAME" 'FILENAME')"
# shellcheck source=/dev/null
-. "${FILENAME%.md}.conf"
+. "${FILENAME%.*}.conf"
envsubst < src/lib/entry.html
diff --git a/v2/src/bin/makemake b/v2/src/bin/makemake
index 20fd6dd..06041b0 100755
--- a/v2/src/bin/makemake
+++ b/v2/src/bin/makemake
@@ -98,14 +98,17 @@ for lang in $(langs); do
for c in pages $(collections); do
if [ "$c" = 'pages' ]; then
filter="$page_ext_filter"
- dir="$CONTENT_PREFIX/$lang"
+ src='page'
+ coll_path=''
else
filter='^$'
- dir="$CONTENT_PREFIX/$lang/$c"
+ src='md'
+ coll_path="$(coll2path "$lang" "$c")"
fi
mds() {
- find "$dir"/*.md 2>/dev/null
+ git ls-files "$CONTENT_PREFIX/$lang/$coll_path"*."$src" |
+ sed 's|\.page$|.md|'
}
exts() {
@@ -120,17 +123,19 @@ for lang in $(langs); do
mds | sed 's/^\(.*\)\.md$/\1.categoryentry \1.indexentry \1.html: \1.conf \1.content/'
mds | sed 's/^\(.*\)\.md$/\1.snippets \1.htmlbody: \1.html/'
if [ "$c" = 'pages' ]; then
+ mds | sed 's|\.md$|\.page|' | varlist "pages.$lang.page"
+ mds | sed "s|^\(.*\).md$|\1.md: \1.page|"
continue
fi
mds | sed 's/^\(.*\)\.md$/\1.xmlentry: \1.htmlbody/'
- echo "$CONTENT_PREFIX/$lang/$c/index.categories: \$($c.$lang.categoryentry)"
- echo "$CONTENT_PREFIX/$lang/$c/index.html: \$($c.$lang.indexentry) $CONTENT_PREFIX/$lang/$c/index.categories"
- echo "$CONTENT_PREFIX/$lang/$c/feed.xml: \$($c.$lang.xmlentry) $CONTENT_PREFIX/$lang/$c/index.categories"
+ echo "$CONTENT_PREFIX/$lang/${coll_path}index.categories: \$($c.$lang.categoryentry)"
+ echo "$CONTENT_PREFIX/$lang/${coll_path}index.html: \$($c.$lang.indexentry) $CONTENT_PREFIX/$lang/${coll_path}index.categories"
+ echo "$CONTENT_PREFIX/$lang/${coll_path}feed.xml: \$($c.$lang.xmlentry) $CONTENT_PREFIX/$lang/${coll_path}index.categories"
- echo "$CONTENT_PREFIX/$lang/$c/index.extrahtml: $CONTENT_PREFIX/$lang/$c/index.html"
- echo "$CONTENT_PREFIX/$lang/$c/index.extrafeeds: $CONTENT_PREFIX/$lang/$c/feed.xml"
+ echo "$CONTENT_PREFIX/$lang/${coll_path}index.extrahtml: $CONTENT_PREFIX/$lang/${coll_path}index.html"
+ echo "$CONTENT_PREFIX/$lang/${coll_path}index.extrafeeds: $CONTENT_PREFIX/$lang/${coll_path}feed.xml"
printf '\n\n'
done
@@ -146,23 +151,28 @@ for lang in $(langs); do
done
collections |
- sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1/index.categories|" |
+ xargs -I% coll2path "$lang" % |
+ sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1index.categories|" |
varlist "all-generated.$lang.categories"
collections |
- sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1/index.extrahtml|" |
+ xargs -I% coll2path "$lang" % |
+ sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1index.extrahtml|" |
varlist "all-generated.$lang.extrahtml"
collections |
- sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1/index.extrafeeds|" |
+ xargs -I% coll2path "$lang" % |
+ sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1index.extrafeeds|" |
varlist "all-generated.$lang.extrafeeds"
collections |
- sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1/index.html|" |
+ xargs -I% coll2path "$lang" % |
+ sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1index.html|" |
varlist "all-generated.$lang.index"
collections |
- sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1/feed.xml|" |
+ xargs -I% coll2path "$lang" % |
+ sed "s|^\(.*\)\$|$CONTENT_PREFIX/$lang/\1feed.xml|" |
varlist "all-generated.$lang.xml"
extensions '.categories' '.extrahtml' '.extrafeeds' '.index' '.xml' |
@@ -172,6 +182,11 @@ for lang in $(langs); do
printf '\n'
done
+git ls-files |
+ grep '\.page' |
+ sed "s|^$CONTENT_PREFIX\(.*\)\.page|\1.md|" > "$CONTENT_PREFIX"/.gitignore
+
+
for e in $(extensions '.categories' '.extrahtml' '.extrafeeds' '.index' '.xml'); do
langs |
sed "s|^\(.*\)\$|\$(all-generated.\1$e)|" |
@@ -180,6 +195,11 @@ done
# shellcheck disable=2016
langs |
+ sed 's|^\(.*\)$|$(pages.\1.md)|' |
+ varlist 'pages-mds'
+
+# shellcheck disable=2016
+langs |
sed 's|^\(.*\)$|$(all-generated.\1)|' |
varlist 'all-generated'
@@ -190,4 +210,5 @@ git ls-files src/ |
git ls-files "$CONTENT_PREFIX"/ |
grep -v '\.md$' |
+ grep -v '\.page$' |
varlist 'static-content'
diff --git a/v2/src/bin/xmlentry b/v2/src/bin/xmlentry
index b0760ae..f6fb6ea 100755
--- a/v2/src/bin/xmlentry
+++ b/v2/src/bin/xmlentry
@@ -26,7 +26,7 @@ help() {
Generate the XML entry for a TIL:
- $ xmlentry src/tils/a-til.md > src/tils/a-til.xml
+ $ xmlentry src/til/a-til.md > src/til/a-til.xml
EOF
}
@@ -68,14 +68,14 @@ eval "$(assert_arg "$FILENAME" 'FILENAME')"
# shellcheck source=/dev/null
-. "${FILENAME%.md}.conf"
+. "${FILENAME%.*}.conf"
envsubst < src/lib/entry.xml
-head -n1 < "${FILENAME%.md}.htmlbody" | htmlesc
+head -n1 < "${FILENAME%.*}.htmlbody" | htmlesc
printf ' </summary>\n'
printf ' <content type="html" xml:base="%s">\n' "${url:?}"
-htmlesc < "${FILENAME%.md}.htmlbody"
+htmlesc < "${FILENAME%.*}.htmlbody"
printf ' </content>\n'
printf ' </entry>\n'
diff --git a/v2/src/content/en/about.md b/v2/src/content/en/about.page
index aac3e67..aac3e67 100644
--- a/v2/src/content/en/about.md
+++ b/v2/src/content/en/about.page
diff --git a/v2/src/content/en/pastebins/raku-tuple-type-annotation.md b/v2/src/content/en/pastebin/raku-tuple-type-annotation.md
index 6c13b39..6c13b39 100644
--- a/v2/src/content/en/pastebins/raku-tuple-type-annotation.md
+++ b/v2/src/content/en/pastebin/raku-tuple-type-annotation.md
diff --git a/v2/src/content/en/pastebins/sicp-exercise-3-19.md b/v2/src/content/en/pastebin/sicp-exercise-3-19.md
index 32f7aa9..32f7aa9 100644
--- a/v2/src/content/en/pastebins/sicp-exercise-3-19.md
+++ b/v2/src/content/en/pastebin/sicp-exercise-3-19.md
diff --git a/v2/src/content/en/remembering-ann.md b/v2/src/content/en/remembering-ann.md
new file mode 100644
index 0000000..9013ad4
--- /dev/null
+++ b/v2/src/content/en/remembering-ann.md
@@ -0,0 +1,186 @@
+---
+
+title: ANN: remembering - Add memory to dmenu, fzf and similar tools
+
+date: 2021-01-26
+
+categories: ann
+
+---
+
+Today I pushed v0.1.0 of [remembering][remembering], a tool to enhance the interactive usability of menu-like tools, such as [dmenu][dmenu] and [fzf][fzf].
+
+## Previous solution
+
+I previously used [yeganesh][yeganesh] fill this gap, but as I started to rely less on Emacs, I added fzf as my go-to tool for doing fuzzy searching on the terminal.
+But I didn't like that fzf always showed the same order of things, when I would only need 3 or 4 commonly used files.
+
+For those who don't know: yeganesh is a wrapper around dmenu that will remember your most used programs and put them on the beginning of the list of executables.
+This is very convenient for interactive prolonged use, as with time the things you usually want are right at the very beginning.
+
+But now I had this thing, yeganesh, that solved this problem for dmenu, but didn't for fzf.
+
+I initially considered patching yeganesh to support it, but I found it more coupled to dmenu than I would desire.
+I'd rather have something that knows nothing about dmenu, fzf or anything, but enhances tools like those in a useful way.
+
+[remembering]: https://euandreh.xyz/remembering/
+[dmenu]: https://tools.suckless.org/dmenu/
+[fzf]: https://github.com/junegunn/fzf
+[yeganesh]: http://dmwit.com/yeganesh/
+
+## Implementation
+
+Other than being decoupled from dmenu, another improvement I though that could be made on top of yeganesh is the programming language choice.
+Instead of Haskell, I went with POSIX sh.
+Sticking to POSIX sh makes it require less build-time dependencies. There aren't any, actually. Packaging is made much easier due to that.
+
+The good thing is that the program itself is small enough ([119 lines][119-lines] on v0.1.0) that POSIX sh does the job just fine, combined with other POSIX utilities such as [getopts][getopts], [sort][sort] and [awk][awk].
+
+[119-lines]: https://euandre.org/git/remembering/tree/remembering?id=v0.1.0
+[getopts]: http://www.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
+[sort]: http://www.opengroup.org/onlinepubs/9699919799/utilities/sort.html
+[awk]: http://www.opengroup.org/onlinepubs/9699919799/utilities/awk.html
+
+The behaviour is: given a program that will read from STDIN and write a single entry to STDOUT, `remembering` wraps that program, and rearranges STDIN so that previous choices appear at the beginning.
+
+Where you would do:
+
+```shell
+$ seq 5 | fzf
+
+ 5
+ 4
+ 3
+ 2
+> 1
+ 5/5
+>
+```
+
+And every time get the same order of numbers, now you can write:
+
+```shell
+$ seq 5 | remembering -p seq-fzf -c fzf
+
+ 5
+ 4
+ 3
+ 2
+> 1
+ 5/5
+>
+```
+
+On the first run, everything is the same. If you picked 4 on the previous example, the following run would be different:
+
+```shell
+$ seq 5 | remembering -p seq-fzf -c fzf
+
+ 5
+ 3
+ 2
+ 1
+> 4
+ 5/5
+>
+```
+
+As time passes, the list would adjust based on the frequency of your choices.
+
+I aimed for reusability, so that I could wrap diverse commands with `remembering` and it would be able to work. To accomplish that, a "profile" (the `-p something` part) stores data about different runs separately.
+
+I took the idea of building something small with few dependencies to other places too:
+- the manpages are written in troff directly;
+- the tests are just more POSIX sh files;
+- and a POSIX Makefile to `check` and `install`.
+
+I was aware of the value of sticking to coding to standards, but I had past experience mostly with programming language standards, such as ECMAScript, Common Lisp, Scheme, or with IndexedDB or DOM APIs.
+It felt good to rediscover these nice POSIX tools, which makes me remember of a quote by [Henry Spencer][poor-unix]:
+
+> Those who do not understand Unix are condemned to reinvent it, poorly.
+
+[poor-unix]: https://en.wikipedia.org/wiki/Henry_Spencer#cite_note-3
+
+## Usage examples
+
+Here are some functions I wrote myself that you may find useful:
+
+### Run a command with fzf on `$PWD`
+
+```shellcheck
+f() {
+ profile="$f-shell-function(pwd | sed -e 's_/_-_g')"
+ file="$(git ls-files | \
+ remembering -p "$profile" \
+ -c "fzf --select-1 --exit -0 --query \"$2\" --preview 'cat {}'")"
+ if [ -n "$file" ]; then
+ # shellcheck disable=2068
+ history -s f $@
+ history -s "$1" "$file"
+ "$1" "$file"
+fi
+}
+```
+
+This way I can run `f vi` or `f vi config` at the root of a repository, and the list of files will always appear on the most used order.
+Adding `pwd` to the profile allows it to not mix data for different repositories.
+
+### Copy password to clipboard
+
+```shell
+choice="$(find "$HOME/.password-store" -type f | \
+ grep -Ev '(.git|.gpg-id)' | \
+ sed -e "s|$HOME/.password-store/||" -e 's/\.gpg$//' | \
+ remembering -p password-store \
+ -c 'dmenu -l 20 -i')"
+
+
+if [ -n "$choice" ]; then
+ pass show "$choice" -c
+fi
+```
+
+Adding the above to a file and binding it to a keyboard shortcut, I can access the contents of my [password store][password-store], with the entries ordered by usage.
+
+[password-store]: https://www.passwordstore.org/
+
+### Replacing yeganesh
+
+Where I previously had:
+
+```shell
+exe=$(yeganesh -x) && exec $exe
+```
+
+Now I have:
+
+```shell
+exe=$(dmenu_path | remembering -p dmenu-exec -c dmenu) && exec $exe
+```
+
+This way, the executables appear on order of usage.
+
+If you don't have `dmenu_path`, you can get just the underlying `stest` tool that looks at the executables available in your `$PATH`. Here's a juicy one-liner to do it:
+
+```shell
+$ wget -O- https://dl.suckless.org/tools/dmenu-5.0.tar.gz | \
+ tar Ozxf - dmenu-5.0/arg.h dmenu-5.0/stest.c | \
+ sed 's|^#include "arg.h"$|// #include "arg.h"|' | \
+ cc -xc - -o stest
+```
+
+With the `stest` utility you'll be able to list executables in your `$PATH` and pipe them to dmenu or something else yourself:
+```shell
+$ (IFS=:; ./stest -flx $PATH;) | sort -u | remembering -p another-dmenu-exec -c dmenu | sh
+```
+
+In fact, the code for `dmenu_path` is almost just like that.
+
+## Conclusion
+
+For my personal use, I've [packaged] `remembering` for GNU Guix and Nix. Packaging it to any other distribution should be trivial, or just downloading the tarball and running `[sudo] make install`.
+
+Patches welcome!
+
+[packaged]: https://euandre.org/git/package-repository/
+[nix-file]: https://euandre.org/git/dotfiles/tree/nixos/not-on-nixpkgs/remembering.nix?id=0831444f745cf908e940407c3e00a61f6152961f
diff --git a/v2/src/content/en/tils/lisp-three-way-conditional.md b/v2/src/content/en/til/lisp-three-way-conditional.md
index 20fbd09..20fbd09 100644
--- a/v2/src/content/en/tils/lisp-three-way-conditional.md
+++ b/v2/src/content/en/til/lisp-three-way-conditional.md
diff --git a/v2/src/content/pt/hea/condicional-ternario-lisp.md b/v2/src/content/pt/hea/condicional-ternario-lisp.md
new file mode 100644
index 0000000..6971827
--- /dev/null
+++ b/v2/src/content/pt/hea/condicional-ternario-lisp.md
@@ -0,0 +1,65 @@
+---
+
+title: Three-way conditional for number signs on Lisp
+
+date: 2021-04-24 3
+
+update: 2021-08-14
+
+categories: lisp scheme common-lisp
+
+---
+
+A useful macro from Paul Graham's [On Lisp][on-lisp] book:
+
+```lisp
+(defmacro nif (expr pos zero neg)
+ (let ((g (gensym)))
+ `(let ((,g ,expr))
+ (cond ((plusp ,g) ,pos)
+ ((zerop ,g) ,zero)
+ (t ,neg)))))
+```
+
+After I looked at this macro, I started seeing opportunities to using it in
+many places, and yet I didn't see anyone else using it.
+
+The latest example I can think of is section 1.3.3 of [Structure and
+Interpretation of Computer Programs][sicp], which I was reading recently:
+
+```scheme
+(define (search f neg-point pos-point)
+ (let ((midpoint (average neg-point pos-point)))
+ (if (close-enough? neg-point post-point)
+ midpoint
+ (let ((test-value (f midpoint)))
+ (cond ((positive? test-value)
+ (search f neg-point midpoint))
+ ((negative? test-value)
+ (search f midpoint pos-point))
+ (else midpoint))))))
+```
+
+Not that the book should introduce such macro this early, but I couldn't
+avoid feeling bothered by not using the `nif` macro, which could even remove
+the need for the intermediate `test-value` variable:
+
+```scheme
+(define (search f neg-point pos-point)
+ (let ((midpoint (average neg-point pos-point)))
+ (if (close-enough? neg-point post-point)
+ midpoint
+ (nif (f midpoint)
+ (search f neg-point midpoint)
+ (midpoint)
+ (search f midpoint pos-point)))))
+```
+
+It also avoids `cond`'s extra clunky parentheses for grouping, which is
+unnecessary but built-in.
+
+As a macro, I personally feel it tilts the balance towards expressivenes
+despite its extra cognitive load toll.
+
+[on-lisp]: http://www.paulgraham.com/onlisptext.html [sicp]:
+https://mitpress.mit.edu/sites/default/files/sicp/index.html
diff --git a/v2/src/content/pt/pastebins/exercicios-sicp-e-19.md b/v2/src/content/pt/pastebin/exercicios-sicp-e-19.md
index 89dacfd..89dacfd 100644
--- a/v2/src/content/pt/pastebins/exercicios-sicp-e-19.md
+++ b/v2/src/content/pt/pastebin/exercicios-sicp-e-19.md
diff --git a/v2/src/content/pt/sobre.md b/v2/src/content/pt/sobre.page
index aac3e67..aac3e67 100644
--- a/v2/src/content/pt/sobre.md
+++ b/v2/src/content/pt/sobre.page
diff --git a/v2/src/lib/base.en.conf b/v2/src/lib/base.en.conf
index 5ced00a..bc90b10 100644
--- a/v2/src/lib/base.en.conf
+++ b/v2/src/lib/base.en.conf
@@ -4,30 +4,41 @@ export site_name="EuAndreh's website"
export lang='en'
-export index_pastebins_title='Pastebins'
+export about='About'
-export index_recent_pastebins_title='Pastebins listing'
+export about_url_name='about.html'
-export index_category_pastebins_title='Pastebins by category'
+export by_category_url_name='by-category.html'
-export index by_category_url_part='by-category.html'
+export homepage_url="$(url-for "$lang/")"
-export feed_pastebins_title="EuAndreh's pastebins"
+export homepage_url_absolute="$(absolute "$homepage_url")"
-export index_tils_title='TIL'
+export about_url="$(url-for "$lang/$about_url_name")"
-export index_recent_tils_title='TIL listing'
-export index_category_tils_title='TIL by category'
+export index__title='Blog'
-export feed_tils_title="EuAndreh's TIL"
+export index_recent__title='Recent articles'
-export about='About'
+export index_category__title='Articles by category'
-export about_url_name='about.html'
+export feed__title="EuAndreh's articles"
-export homepage_url="$(url-for "$lang/")"
-export homepage_url_absolute="$(absolute "$homepage_url")"
+export index_pastebin_title='Pastebins'
-export about_url="$(url-for "$lang/$about_url_name")"
+export index_recent_pastebin_title='Pastebins listing'
+
+export index_category_pastebin_title='Pastebins by category'
+
+export feed_pastebin_title="EuAndreh's pastebins"
+
+
+export index_til_title='TIL'
+
+export index_recent_til_title='TIL listing'
+
+export index_category_til_title='TIL by category'
+
+export feed_til_title="EuAndreh's TIL"
diff --git a/v2/src/lib/base.pt.conf b/v2/src/lib/base.pt.conf
index fe03f42..5703bed 100644
--- a/v2/src/lib/base.pt.conf
+++ b/v2/src/lib/base.pt.conf
@@ -4,30 +4,41 @@ export site_name="EuAndreh's website"
export lang='pt'
-export index_pastebins_title='Pastebins'
+export about='About'
-export index_recent_pastebins_title='Pastebins listing'
+export about_url_name='sobre.html'
-export index_category_pastebins_title='Pastebins by category'
+export by_category_url_name='por-categoria.html'
-export index by_category_url_part='by-category.html'
+export homepage_url="$(url-for "$lang/")"
-export feed_pastebins_title="EuAndreh's pastebins"
+export homepage_url_absolute="$(absolute "$homepage_url")"
-export index_tils_title='TIL'
+export about_url="$(url-for "$lang/$about_url_name")"
-export index_recent_tils_title='TIL listing'
-export index_category_tils_title='TIL by category'
+export index__title='Blog'
-export feed_tils_title="EuAndreh's TIL"
+export index_recent__title='Artigos recentes'
-export about='About'
+export index_category__title='Artigos por categoria'
-export about_url_name='about.html'
+export feed__title="Artigos do EuAndreh"
-export homepage_url="$(url-for "$lang/")"
-export homepage_url_absolute="$(absolute "$homepage_url")"
+export index_pastebin_title='Pastebins'
-export about_url="$(url-for "$lang/$about_url_name")"
+export index_recent_pastebin_title='Pastebins listing'
+
+export index_category_pastebin_title='Pastebins by category'
+
+export feed_pastebin_title="EuAndreh's pastebins"
+
+
+export index_til_title='HEA'
+
+export index_recent_til_title='HEA recentes'
+
+export index_category_til_title='HEA por categoria'
+
+export feed_til_title="HEA do EuAndreh"
diff --git a/v2/src/lib/commencement.en.conf b/v2/src/lib/commencement.en.conf
new file mode 100644
index 0000000..9b19b18
--- /dev/null
+++ b/v2/src/lib/commencement.en.conf
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+export article_collection_name=''
+
+export pastebin_collection_name='pastebin'
+
+export til_collection_name='til'
diff --git a/v2/src/lib/commencement.pt.conf b/v2/src/lib/commencement.pt.conf
new file mode 100644
index 0000000..e3b9544
--- /dev/null
+++ b/v2/src/lib/commencement.pt.conf
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+export article_collection_name=''
+
+export pastebin_collection_name='pastebin'
+
+export til_collection_name='hea'