blog

git clone https://git.ce9e.org/blog.git

commit
0b5e614b8d959c143ea7a8d14a0f026d33dcc5e2
parent
206cd6e541a95edabfcc5d3a5529a4eac47a0722
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-11-03 09:12
rm shift-heading-level

Diffstat

M Makefile 2 +-
M _content/posts/2014-09-09-patch-theory/index.md 46 ++++++++++++++++------------------------------
M _content/posts/2015-03-20-resize-partition-on-crypted-disk/index.md 6 +++---
M _content/posts/2016-03-05-color-contrast/index.md 16 ++++++++--------
M _content/posts/2016-06-04-rtl-css/index.md 12 ++++++------
M _content/posts/2016-12-22-web-is-not-visual/index.md 6 +++---
M _content/posts/2017-04-18-ghost-in-the-shell-review/index.md 8 ++++----
M _content/posts/2017-04-21-math-pairs/index.md 8 ++++----
M _content/posts/2017-06-26-simple-language/index.md 10 +++++-----
M _content/posts/2017-09-04-rationality/index.md 12 ++++++------
M _content/posts/2017-11-05-TDD/index.md 10 +++++-----
M _content/posts/2017-11-20-exponential/index.md 8 ++++----
M _content/posts/2017-12-18-personalization/index.md 8 ++++----
M _content/posts/2017-12-30-icons/index.md 10 +++++-----
M _content/posts/2018-01-14-consensus-meetings/index.md 10 +++++-----
M _content/posts/2018-05-28-zen/index.md 4 ++--
M _content/posts/2018-10-28-aria-quirks/index.md 18 +++++++++---------
M _content/posts/2019-01-13-visual/index.md 6 +++---
M _content/posts/2019-05-02-debian-packages/index.md 10 +++++-----
M _content/posts/2019-06-24-terminal-colors/index.md 14 +++++++-------
M _content/posts/2020-01-20-open-source/index.md 14 +++++++-------
M _content/posts/2020-05-16-pad/index.md 8 ++++----
M _content/posts/2020-10-10-thunderbird/index.md 8 ++++----
M _content/posts/2020-11-21-file-type-101/index.md 10 +++++-----
M _content/posts/2020-12-28-wayland-wm/index.md 12 ++++++------
M _content/posts/2021-04-03-zero-cost-optimizations/index.md 14 +++++++-------
M _content/posts/2021-08-20-linux-service-architecture/index.md 8 ++++----
M _content/posts/2022-02-20-minimalism/index.md 12 ++++++------
M _content/posts/2022-06-25-hard-work/index.md 4 ++--
M _content/posts/2022-09-10-contrast-algorithms/index.md 10 +++++-----
M _content/posts/2022-12-03-my-window-manager-setup/index.md 12 ++++++------
M _content/posts/2023-01-15-state-of-wayland/index.md 8 ++++----
M _content/posts/2023-01-29-python-async-loops/index.md 44 ++++++++++++++++++++++----------------------
M _content/posts/2023-02-26-flow-relative-layout/index.md 6 +++---
M _content/posts/2023-03-30-tui/index.md 20 ++++++++++----------
M _content/posts/2023-09-28-mfa/index.md 26 +++++++++++++-------------
M _content/posts/2023-10-13-logging/index.md 12 ++++++------
M _content/posts/2023-10-29-jmap-calendars/index.md 4 ++--

38 files changed, 221 insertions, 235 deletions


diff --git a/Makefile b/Makefile

@@ -22,7 +22,7 @@ build/%.html: _content/%.html _content/%.yml _templates/*.html build.py
   22    22 	python build.py _templates/base.html $< _content/$*.yml > $@
   23    23 
   24    24 _content/%.html: _content/%.md
   25    -1 	pandoc --shift-heading-level-by=1 $< -o $@
   -1    25 	pandoc $< -o $@
   26    26 	sed -i 's/<tr class="header">/<tr>/g' $@
   27    27 
   28    28 build/%.png: _content/%.png

diff --git a/_content/posts/2014-09-09-patch-theory/index.md b/_content/posts/2014-09-09-patch-theory/index.md

@@ -1,5 +1,4 @@
    1    -1 Introduction
    2    -1 ============
   -1     1 ## Introduction
    3     2 
    4     3 Versioning systems have been important tools in software development
    5     4 (and other areas) for a long time. In recent years, git has been the
@@ -35,8 +34,7 @@ version control for everyone, like a way to eliminate the need for
   35    34 manual merges altogether or making git understand that I simply changed
   36    35 indentation.
   37    36 
   38    -1 The Basics
   39    -1 ==========
   -1    37 ## The Basics
   40    38 
   41    39 Say we have a set `S` of *states*. We always use capital letters for
   42    40 states. For two states `A, B ∈ S` we say `(A, B)` or shorter `AB` is the
@@ -51,8 +49,7 @@ Note that there is some kind of natural composition of changes: When I
   51    49 first change from `A` to `B`, and then from `B` to `C`, I have changed
   52    50 from `A` to `C` (in formula: `AB * BC = AC`).
   53    51 
   54    -1 Patches
   55    -1 =======
   -1    52 ## Patches
   56    53 
   57    54 Now imagine you have a repo with some files, one of them called
   58    55 "main.py". Then you delete this file. This, in the terms we already
@@ -73,8 +70,7 @@ Then again, I would much prefer an axiomatic approach over actually
   73    70 defining that relation in every detail. Too strict definitions always
   74    71 carry the danger of incompatibility with related theories.
   75    72 
   76    -1 The Equivalence Relation
   77    -1 ------------------------
   -1    73 ### The Equivalence Relation
   78    74 
   79    75 I propose the following axioms for the equivalence relation `~`:
   80    76 
@@ -107,8 +103,7 @@ based patches, this is only possible if `AC` does not touch any of the
  107   103 lines that `CD` changes. And because in the end, both paths arrive at
  108   104 `D`, this must mean that `AC` and `CD` are equivalent.
  109   105 
  110    -1 Corolarries
  111    -1 -----------
   -1   106 ### Corolarries
  112   107 
  113   108 -   For 1, 2 and 4 there is actually equivalence
  114   109 
@@ -117,8 +112,7 @@ Corolarries
  117   112 -   `AA ~ BC <=> B = C` follows from 2 and 4 and shows that there is
  118   113     an identity patch we call `id`.
  119   114 
  120    -1 Applying a Patch
  121    -1 ----------------
   -1   115 ### Applying a Patch
  122   116 
  123   117 We can interpret a patch `a` as a function (which is compatible to the
  124   118 set theoretic definition of a function) with the following domain and
@@ -129,8 +123,7 @@ codomain:
  129   123 
  130   124 We say, a patch `a` is applicable to a state `A`, iff `A ∈ dom(A)`.
  131   125 
  132    -1 Composing patches
  133    -1 =================
   -1   126 ## Composing patches
  134   127 
  135   128 Up until now we have a notion of what a single patch is. We know how to
  136   129 apply it where it is applicable.
@@ -164,8 +157,7 @@ defined as `ab := [XZ]`.
  164   157 
  165   158 -   It only creates a conflict if `cod(a) ∩ dom(b)` is empty
  166   159 
  167    -1 Independence
  168    -1 ------------
   -1   160 ### Independence
  169   161 
  170   162 Axiom 4 can now be reformulated in terms of patches:
  171   163 
@@ -174,14 +166,12 @@ Axiom 4 can now be reformulated in terms of patches:
  174   166 Patches `a, b ∈ P` for which `ab = ba` is true are called *independent*.
  175   167 `id` is independent from all patches.
  176   168 
  177    -1 Further Ideas
  178    -1 =============
   -1   169 ## Further Ideas
  179   170 
  180   171 These are notes on ideas on some parts that may be interesting to work
  181   172 on in the future.
  182   173 
  183    -1 Simple Questions
  184    -1 ----------------
   -1   174 ### Simple Questions
  185   175 
  186   176 There are some questions about patches that seem harmless but are not
  187   177 all that easy to get an anser for. Examples:
@@ -191,8 +181,7 @@ all that easy to get an anser for. Examples:
  191   181 -   Is there a patch `a` with `dom(a) ∩ cod(a) != 0` except
  192   182     for `id`?
  193   183 
  194    -1 Patch sets
  195    -1 ----------
   -1   184 ### Patch sets
  196   185 
  197   186 The composition I gave in the previous chapter is not associative.
  198   187 Example: Say patches `a, b` conflict. Then `(ab)b⁻¹` is not defined,
@@ -208,8 +197,7 @@ what the "order that makes most sense" should be and whether it is
  208   197 unambiguous. And while most things I said before are compatible with
  209   198 common version control systems we use today, this is not.
  210   199 
  211    -1 State as Patches
  212    -1 ----------------
   -1   200 ### State as Patches
  213   201 
  214   202 Now that we have patches we can fix one state we may call `0` and
  215   203 identify every state `A ∈ S` with the patch `[0A]` where `0` is
@@ -219,10 +207,9 @@ Of course this is only a small subset of patches (more specifically, it
  219   207 is `{a ∈ P | 0 ∈ dom(a)}`). But it may have some interesting structural
  220   208 properties.
  221   209 
  222    -1 Conflicts
  223    -1 ---------
   -1   210 ### Conflicts
  224   211 
  225    -1 ### Group structure
   -1   212 #### Group structure
  226   213 
  227   214 The set of patches `P` has a structure similar to a group: There is a
  228   215 neutral element `id` and for every element `a`, there is an inverse
@@ -234,7 +221,7 @@ get a whole lot nicer if we could manage to extend `P` to contain one or
  234   221 many elements that represent conflict. I did not come up with a sensible
  235   222 way to force `P` into a group, but I guess it would be worth it.
  236   223 
  237    -1 ### Manual conflict resultion
   -1   224 #### Manual conflict resultion
  238   225 
  239   226 An issue that I imagine is very important in developing actual version
  240   227 control systems is aiding humans in resolving conflicts. I did only
@@ -248,8 +235,7 @@ human in a humane way is something that needs to be done.
  248   235 
  249   236 I did not yet think about it at all.
  250   237 
  251    -1 Conclusion
  252    -1 ==========
   -1   238 ## Conclusion
  253   239 
  254   240 I believe I have come up with a stable foundation for patch theory. The
  255   241 idea to define patches as equivalence classes over the square of states

diff --git a/_content/posts/2015-03-20-resize-partition-on-crypted-disk/index.md b/_content/posts/2015-03-20-resize-partition-on-crypted-disk/index.md

@@ -9,7 +9,7 @@ The trouble is now that the installer chose to use only 10GB for the root
    9     9 partition which I used up in the first week. So now I was tasked with resizing
   10    10 the partitions.
   11    11 
   12    -1 # What I already knew
   -1    12 ## What I already knew
   13    13 
   14    14 In the past I had used [gparted](http://gparted.org/) for task like this one.
   15    15 Unfortunately, gparted does not support encryptet discs.  I was very
@@ -24,7 +24,7 @@ uses all the rest):
   24    24 2.	move `home` to the end of the disc
   25    25 3.	grow `root`
   26    26 
   27    -1 # the actual situation
   -1    27 ## the actual situation
   28    28 
   29    29 The disc layout was roughly like this:
   30    30 
@@ -41,7 +41,7 @@ simplify my task:
   41    41 -	logical volumes can use available space anywhere on the physical volume. So
   42    42 	there is no need to "move" `root`.
   43    43 
   44    -1 # what I had to do
   -1    44 ## what I had to do
   45    45 
   46    46 -	The necessary operations can not be applied to mounted volumes. So I had to
   47    47 	boot into a live system.

diff --git a/_content/posts/2016-03-05-color-contrast/index.md b/_content/posts/2016-03-05-color-contrast/index.md

@@ -12,9 +12,9 @@ personally prefer Sass, so all examples are written in that language.
   12    12 One final note: I assume that you have a basic understanding of working with
   13    13 colors, especially in CSS.
   14    14 
   15    -1 # Solid colors
   -1    15 ## Solid colors
   16    16 
   17    -1 ## Definition
   -1    17 ### Definition
   18    18 
   19    19 So what is color contrast? There are [many
   20    20 definitions](https://en.wikipedia.org/wiki/Color_contrast), but the W3C chose
@@ -85,7 +85,7 @@ rationale for the 0.05 is. It prevents the formula from going to infinity
   85    85 for near-black colors, but I find that it still produces overly high results
   86    86 for those.
   87    87 
   88    -1 ## Implementations
   -1    88 ### Implementations
   89    89 
   90    90 I have seen three types of functions that you may wish to have in your CSS
   91    91 preprocessing code:
@@ -111,7 +111,7 @@ library called [sass-a11y](https://github.com/at-import/sass-a11y) which
  111   111 contains a function of the second type called `a11y-contrast()`. This one seems
  112   112 to be correct.
  113   113 
  114    -1 # Transparent colors
   -1   114 ## Transparent colors
  115   115 
  116   116 So now that we know how to calculate color contrast of solid colors, let's turn
  117   117 to transparent colors. This topic has been raised by [Lea
@@ -153,7 +153,7 @@ I wanted to come up with an algorithm that could easily be implemented in
  153   153 existing libraries, so breaking the API was undesirable. So the final sections
  154   154 of this article will describe the approach I took.
  155   155 
  156    -1 ## Transparent backgrounds
   -1   156 ### Transparent backgrounds
  157   157 
  158   158 Let's turn to the issue of the unknown backdrop color first. These are some
  159   159 approaches I could think of:
@@ -215,7 +215,7 @@ in that range. Otherwise, it is the minimum of the white/black cases:
  215   215 }
  216   216 ```
  217   217 
  218    -1 ## Background/foreground
   -1   218 ### Background/foreground
  219   219 
  220   220 In the case of solid colors, it was not relevant which of the colors was
  221   221 background and which was foreground. Now it is: When a transparent foreground
@@ -252,7 +252,7 @@ contrast and its swapped version, I think it is a sensible approach to use a
  252   252 }
  253   253 ```
  254   254 
  255    -1 ## Implementations
   -1   255 ### Implementations
  256   256 
  257   257 -   Lea Verou created a [tool](https://leaverou.github.io/contrast-ratio/)
  258   258     written in JavaScript that reports minimum and maximum possible contrasts
@@ -267,7 +267,7 @@ contrast and its swapped version, I think it is a sensible approach to use a
  267   267     [sass-planifolia](https://github.com/xi/sass-planifolia) which implements
  268   268     the symmetric minimal contrast algorithm.
  269   269 
  270    -1 # Conclusion
   -1   270 ## Conclusion
  271   271 
  272   272 This article covered many details about color contrast as well as a new
  273   273 algorithm that supports transparency and can be implemented in existing

diff --git a/_content/posts/2016-06-04-rtl-css/index.md b/_content/posts/2016-06-04-rtl-css/index.md

@@ -1,4 +1,4 @@
    1    -1 # What is it and why does it concern me?
   -1     1 ## What is it and why does it concern me?
    2     2 
    3     3 Most western scripts are read from left to right (LTR), so this is what many
    4     4 web developers think about when writing CSS. But some scripts, such as Arabic
@@ -8,7 +8,7 @@ direction. The complete layout should also be mirrored to match it.
    8     8 So say you want to write CSS that can be used with both text directions. What
    9     9 do you have to think about?
   10    10 
   11    -1 # The problem
   -1    11 ## The problem
   12    12 
   13    13 HTML and CSS have advanced support for different text directions. You can use
   14    14 the [`dir`
@@ -22,7 +22,7 @@ The only issue is that `left` and `right` are actually physical directions and
   22    22 will not change with text direction, so any `float: left` or `margin-right:
   23    23 1em` will not adapt with the text direction.
   24    24 
   25    -1 # The solution
   -1    25 ## The solution
   26    26 
   27    27 Just as relative units such as `em` or `%` are better than absolute `px`,
   28    28 relative directions like `start` and `end` are preferable to `left` and
@@ -31,7 +31,7 @@ it and `start` / `end` are already available for the [`text-align`
   31    31 property](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) in many
   32    32 browsers.
   33    33 
   34    -1 # The workaround
   -1    34 ## The workaround
   35    35 
   36    36 As long as the proper solution is not available, here is a simple way to
   37    37 convert a LTR stylesheet to RTL.  I am not exactly sure that this is the
@@ -65,7 +65,7 @@ complete list, but it should be sufficient:
   65    65     In all other cases this is actually worse, apart from being hard to
   66    66     maintain.
   67    67 
   68    -1 # Outlook: vertical text
   -1    68 ## Outlook: vertical text
   69    69 
   70    70 CSS3 will take the support for non-latin scripts even further and add support
   71    71 for vertical (e.g. top-to-bottom) text. Note however that most vertical scripts
@@ -76,7 +76,7 @@ One important thing to remember is that many new keywords from these specs use
   76    76 abbreviations such as `vertical-rl` for "vertical-right-left". But you probably
   77    77 should not mix that workaround with these new properties anyway.
   78    78 
   79    -1 # Further reading
   -1    79 ## Further reading
   80    80 
   81    81 -   <https://github.com/MohammadYounes/rtlcss>
   82    82 -   <http://www.rtl-this.com/>

diff --git a/_content/posts/2016-12-22-web-is-not-visual/index.md b/_content/posts/2016-12-22-web-is-not-visual/index.md

@@ -3,7 +3,7 @@ the first universally accessible medium. I am not sure if this is actually what
    3     3 happened. But a lot of things start to make sense if you look at them from this
    4     4 particular perspective.
    5     5 
    6    -1 # Birth of a new medium
   -1     6 ## Birth of a new medium
    7     7 
    8     8 Our story begins with an old medium: Print. The invention of the
    9     9 printing press around 1440 made books availabe to a lot of people. Scolars like
@@ -30,7 +30,7 @@ displays, screen readers or print it on paper. They can be controlled with
   30    30 mouse, keyboard, touchscreen or voicecontrol. Whatever a person needs, the
   31    31 computer can be programmed to provide the right interface.
   32    32 
   33    -1 # The dark ages
   -1    33 ## The dark ages
   34    34 
   35    35 This could have been a golden age for people with physical or mental
   36    36 disabilities who had had trouble with reading before. The new medium finally
@@ -47,7 +47,7 @@ This would hava been fine, except that the people who created websites started
   47    47 believing it, too. They forgot about semantics and only thought about making
   48    48 the content look good in common browsers.
   49    49 
   50    -1 # A new hope
   -1    50 ## A new hope
   51    51 
   52    52 In 2007, finally something happened. People started carrying mobile computers
   53    53 with them. These had much smaller screens than traditional computers and were

diff --git a/_content/posts/2017-04-18-ghost-in-the-shell-review/index.md b/_content/posts/2017-04-18-ghost-in-the-shell-review/index.md

@@ -8,7 +8,7 @@ to look at what the movie got right in terms of story.
    8     8 **Spoiler alert**: I will talk freely, assuming that you know all there is to
    9     9 know about the franchise (or do not care).
   10    10 
   11    -1 # The GITS franchise
   -1    11 ## The GITS franchise
   12    12 
   13    13 There have been [many iterations][3] of ghost in the shell already. The most
   14    14 famous one is probably the 1995 movie. I have seen most iterations, but I am
@@ -30,7 +30,7 @@ GITS tackles many topics like AI, individuality, gender, violence, and much
   30    30 more. There are so many facets to the cyborg idea, and GITs deals with most of
   31    31 them.
   32    32 
   33    -1 # Donna Haraway
   -1    33 ## Donna Haraway
   34    34 
   35    35 At some time I stumble across the ["cyborg manifesto"][1] by radical feminist
   36    36 Donna Haraway. Haraway's style of writing is somewhat special. She plants ideas
@@ -54,7 +54,7 @@ filled with ex-military cyborgs that have to find their place. And sure enough,
   54    54 Donna Haraway shows up in the middle of this world as a [forensic doctor in
   55    55 Innocence][2].
   56    56 
   57    -1 # The Hollywood movie
   -1    57 ## The Hollywood movie
   58    58 
   59    59 First of, the new movie copies many scenes and ideas from the previous
   60    60 iterations, and it honestly does a great job with that. Imagine how thrilled I
@@ -84,7 +84,7 @@ origins in military and capitalism and its revolutionary potential. Sure, the
   84    84 movie is not a milestone of intellectuality, but it does a good job of
   85    85 introducing this conflict and reminding us that it is real and current.
   86    86 
   87    -1 # Conclusion
   -1    87 ## Conclusion
   88    88 
   89    89 I do not want to argue that this is a great movie. It certainly has many flaws.
   90    90 But why does everyone say that it removed the philosophy from the story?  Sure,

diff --git a/_content/posts/2017-04-21-math-pairs/index.md b/_content/posts/2017-04-21-math-pairs/index.md

@@ -9,14 +9,14 @@ quality of the algorithm would be:
    9     9 -	No person should be singled out.
   10    10 -	It should be simple to explain what everyone has to do.
   11    11 
   12    -1 # First approach: Lower bound
   -1    12 ## First approach: Lower bound
   13    13 
   14    14 In a group of `n` people, there are `n * (n - 1) / 2` pairs in total. At one
   15    15 time, there can be at most `floor(n / 2)` pairs. So if `n` is even the minimal
   16    16 number of rounds is `n - 1`, if it is odd it is `n`. This makes sense because
   17    17 each person has to speak to `n - 1` people.
   18    18 
   19    -1 # Second approach: Divide and conquer
   -1    19 ## Second approach: Divide and conquer
   20    20 
   21    21 The problem can be solved with a simple recursive algorithm:
   22    22 
@@ -41,7 +41,7 @@ This algorithm is simple, but not optimal.  Let's look at the example of
   41    41 In the later rounds we have people waiting who could pair up. We should skip
   42    42 the first round instead.
   43    43 
   44    -1 # Optimal solution: Distances
   -1    44 ## Optimal solution: Distances
   45    45 
   46    46 Let's first concentrate on the case where `n` is odd.
   47    47 
@@ -85,7 +85,7 @@ def pairs(n):
   85    85 		print(r)
   86    86 ```
   87    87 
   88    -1 # Conclusion
   -1    88 ## Conclusion
   89    89 
   90    90 The second algorithm actually is optimal in terms of time. It is also
   91    91 relatively easy to understand. The only issue is that, in the even case, person

diff --git a/_content/posts/2017-06-26-simple-language/index.md b/_content/posts/2017-06-26-simple-language/index.md

@@ -3,7 +3,7 @@ of this project was that it would have a "simple German" translation in
    3     3 addition to a German one. Little did I know back then that this was the
    4     4 beginning of a fantastic journey.
    5     5 
    6    -1 # The Standards
   -1     6 ## The Standards
    7     7 
    8     8 First things first. There is a standard that requires us to provide simple
    9     9 language alternatives:
@@ -43,7 +43,7 @@ helped out with some more tangible proposals ([basiceng][7] and [wpsimple][8])
   43    43 in October; and sometime in December, the ["simple"
   44    44 variant subtag][9] was finally accepted.
   45    45 
   46    -1 # Summary of the Discussion
   -1    46 ## Summary of the Discussion
   47    47 
   48    48 You may ask yourself: "Why did it take three months of discussion to add four
   49    49 lines to that registry?" There are many reasons for that.
@@ -95,7 +95,7 @@ fall back to `de-simple` if the more specific variant was not available.
   95    95 > en-US-simple-VoA and en-US-simple-odgenbe and en-US-simple-wp that might
   96    96 > work). — [Shawn Steele][12]
   97    97 
   98    -1 # Is a new language variant the Answer?
   -1    98 ## Is a new language variant the Answer?
   99    99 
  100   100 The question remains whether the accessibility issue can be solved on a
  101   101 language level alone.  Some people argued that complex websites cannot be
@@ -122,7 +122,7 @@ to complexity as well:
  122   122 > well it is organized (for example using headers, lists, and structures), and
  123   123 > how it is presented (font, spacing, width, etc.). — [Shadi Abou-Zahra][22]
  124   124 
  125    -1 # Adoption
   -1   125 ## Adoption
  126   126 
  127   127 More than a year later I came back to see who had adopted this new language
  128   128 tag. Unsurprisingly, nobody seemed to have noticed. We had failed to get the
@@ -145,7 +145,7 @@ publish simple content already. An obvious choice is [wikipedia][23] (which had
  145   145 [ferocious debates][15] about deleting its simple version). But there are
  146   146 probably more publishers that might benefit from this.
  147   147 
  148    -1 # Conclusion
   -1   148 ## Conclusion
  149   149 
  150   150 What have we learned? Naming languages is a fascinating and difficult area.
  151   151 Simple language is a controversial topic that cannot yet find consensus in the

diff --git a/_content/posts/2017-09-04-rationality/index.md b/_content/posts/2017-09-04-rationality/index.md

@@ -4,7 +4,7 @@
    4     4 >
    5     5 > — Donna Haraway, Situated Knowledge
    6     6 
    7    -1 # Something's cooking
   -1     7 ## Something's cooking
    8     8 
    9     9 For years I heard about debates between scientists and creationists in the USA.
   10    10 I largely ignored those debates because it felt like it was mostly a media
@@ -31,7 +31,7 @@ article might not be for you.
   31    31 
   32    32 [^6]:	If you understand german, [this articel on Lann Hornscheidt](https://sciencefiles.org/2014/10/31/profxin-lann-hornscheidt-von-der-humboldt-universitat-entfernen/){hreflang=de} is another example.
   33    33 
   34    -1 # Empiricism
   -1    34 ## Empiricism
   35    35 
   36    36 "Science" can be understood in a wider sense, but many people understand it as
   37    37 "empirical research". This means that you collect a lot of data and deduce
@@ -51,7 +51,7 @@ Imagine you are a brain in a vat that is connected to a computer simulation
   51    51 saying that you cannot be certain that this is not the case.  Everything you
   52    52 sense, all data you collect could be completely unrelated to the real world.
   53    53 
   54    -1 # Rationality
   -1    54 ## Rationality
   55    55 
   56    56 So if you do not trust your senses, the only thing you have left is your
   57    57 mind.[^5]  Descartes famously took this route and found "I think, therefore I
@@ -77,7 +77,7 @@ but we are incapable of thinking that.[^2]
   77    77 [^5]:	I omit the question what "mind" actually means here. What is the
   78    78 	difference between "knowing" and "understanding"? Can a machine ever "think"?
   79    79 
   80    -1 # Falsification
   -1    80 ## Falsification
   81    81 
   82    82 So clearly there is no way of *knowing* something. But we can still guess.
   83    83 Science ultimately is about making the best guesses possible, or making *less
@@ -99,7 +99,7 @@ maybe emotions).
   99    99 	falsified, "A non-white swan exists" can only be verified.
  100   100 [^4]:	Politics, not policy!
  101   101 
  102    -1 # Choosing a Theory
   -1   102 ## Choosing a Theory
  103   103 
  104   104 > All models are wrong, but some are useful
  105   105 >
@@ -119,7 +119,7 @@ Finally, choosing a theory is not a-political: I could believe that jews are
  119   119 conspiring to oppress us all.  There is probably no data that disproves this
  120   120 theory. But I choose to be non-racist.
  121   121 
  122    -1 # Conclusion
   -1   122 ## Conclusion
  123   123 
  124   124 I do see some issues with gender studies, but I also think that their
  125   125 consequent refusal of the very concept of objectivity is interesting and

diff --git a/_content/posts/2017-11-05-TDD/index.md b/_content/posts/2017-11-05-TDD/index.md

@@ -10,7 +10,7 @@ I personally feel that TDD is not compatible with my approach to programming.
   10    10 I will try to break down that approach by explaining what I don't like about
   11    11 TDD.
   12    12 
   13    -1 # Design vs Production
   -1    13 ## Design vs Production
   14    14 
   15    15 For me, programming is about finding the best solution to a problem. It is
   16    16 *not* about writing code. These two approaches are often called "design"
@@ -40,7 +40,7 @@ If software is designed in this way there is no clear line between spec and
   40    40 implementation detail. The code is an immediate and concise representation of a
   41    41 mental model.  It is its own spec and documentation all at once.
   42    42 
   43    -1 # The process of design
   -1    43 ## The process of design
   44    44 
   45    45 It is hard to pin down how design is actually done. I guess I learned it
   46    46 through experience.  Rich Hickey did a great explanation of some of the aspects
@@ -65,7 +65,7 @@ and ruling out the unlikely ones. It really works best inside of my head. Any
   65    65 physical representation like writing or sketching mostly slows me down. The
   66    66 occasional scribble can be really helpful though.
   67    67 
   68    -1 # Limitations
   -1    68 ## Limitations
   69    69 
   70    70 Sure, there are some limitations to this approach. You may not always be able
   71    71 to express your thoughts in code directly. Maybe the programming language can
@@ -82,7 +82,7 @@ and everyone else. Instead, I believe, we should encourage and empower people
   82    82 to understand the actual code in the first place, at least to some reasonable
   83    83 degree.
   84    84 
   85    -1 # What is wrong with TDD?
   -1    85 ## What is wrong with TDD?
   86    86 
   87    87 > at times I got sucked into that fundamentalist vortex, feeling bad about not
   88    88 > following the true gospel. Then I'd try test-first for a few weeks, only to
@@ -120,7 +120,7 @@ I totally agree that this is a good trade in some situations. But we need to
  120   120 acknowledge that it is actually distracting and harmful in many others. So
  121   121 while I think that testing can be beneficial, TDD is a different story.
  122   122 
  123    -1 # Conclusion
   -1   123 ## Conclusion
  124   124 
  125   125 You may have a completely different approach to programming. Maybe TDD gives
  126   126 you the structure you need to design and implement great software. Or maybe a

diff --git a/_content/posts/2017-11-20-exponential/index.md b/_content/posts/2017-11-20-exponential/index.md

@@ -2,13 +2,13 @@ How often do you read sentences like "the problem is growing exponentially" or
    2     2 "technological progress is exponential"? Do you understand what this should
    3     3 tell you? I don't.
    4     4 
    5    -1 # It's a relation
   -1     5 ## It's a relation
    6     6 
    7     7 First of all, "exponential" is not a property of a series. It is a *relation*.
    8     8 A problem cannot grow exponentially, but it can grow exponentially *in relation
    9     9 to* time or people involved or whatever.
   10    10 
   11    -1 # It depends on units
   -1    11 ## It depends on units
   12    12 
   13    13 Much more important, however, is this: "Exponential" depends on the *unit* that
   14    14 is used. For example, think about a tone whose frequency rises exponentially in
@@ -21,7 +21,7 @@ consumption. If you look at per capita consumption instead, you may well find
   21    21 that it has stayed constant. Same for "price of X has grown exponentially":
   22    22 Have they taken inflation into account?
   23    23 
   24    -1 # It is probably not the right thing
   -1    24 ## It is probably not the right thing
   25    25 
   26    26 Here is the third issue: Remember when people at your bank tell you that a
   27    27 "1.3% interest rate does not seem like much now, but think about what it will
@@ -36,7 +36,7 @@ short-term properties to exponential growth, but is vastly different in the
   36    36 long term. Again, the long term is what is interesting about exponential
   37    37 growth.
   38    38 
   39    -1 # Conclusion
   -1    39 ## Conclusion
   40    40 
   41    41 Maybe I should just accept that "exponential" has become a fancy way to say
   42    42 "hugely". That would be sad because exponential growth is a powerful concept if

diff --git a/_content/posts/2017-12-18-personalization/index.md b/_content/posts/2017-12-18-personalization/index.md

@@ -9,7 +9,7 @@ power in the hands of authors and too little power in the hands of users to
    9     9 allow effective personalization. Still, I will try to find some practical
   10    10 guidelines that may facilitate better personalization on the web.
   11    11 
   12    -1 # What exactly is meant by "personalization"
   -1    12 ## What exactly is meant by "personalization"
   13    13 
   14    14 > Personalization involves tailoring aspects of the user experience to meet the
   15    15 > preferences or needs of the user. Technology holds the promise of being
@@ -34,7 +34,7 @@ personalization settings. But that would actually be really bad for privacy.
   34    34 Instead, personalization should ideally happen completely in the user agent
   35    35 without the application even noticing.
   36    36 
   37    -1 # Why do we have CSS?
   -1    37 ## Why do we have CSS?
   38    38 
   39    39 Imagine a world where the rendering of a webpage was completely controlled by
   40    40 the browser.  In that world, personalization would be easy. It would probably
@@ -68,7 +68,7 @@ In the alert case, the additional distinction between success and danger is
   68    68 probably implicit from the content. But in other cases, the additional
   69    69 semantics may be essential.
   70    70 
   71    -1 # Overwriting CSS
   -1    71 ## Overwriting CSS
   72    72 
   73    73 Now that we are stuck with CSS, the only option to enable personalization is to
   74    74 overwrite it. This is also why the [User Agent Accessibility
@@ -108,7 +108,7 @@ removed support for user level
  108   108 stylesheets](https://bugs.chromium.org/p/chromium/issues/detail?id=347016) in
  109   109 2014.
  110   110 
  111    -1 # Conclusion
   -1   111 ## Conclusion
  112   112 
  113   113 The web is the most accessible medium we have ever had. But still, it is far
  114   114 from perfect. Semantic HTML enables us to use a wide range of representations –

diff --git a/_content/posts/2017-12-30-icons/index.md b/_content/posts/2017-12-30-icons/index.md

@@ -6,7 +6,7 @@ The W3C's [Cognitive Accessibility Roadmap and Gap
    6     6 Analysis](https://www.w3.org/TR/coga-gap-analysis/) proposes to allow users to
    7     7 personalize icons. This is my proposal on how that could be done.
    8     8 
    9    -1 # A brief history of icons on the web
   -1     9 ## A brief history of icons on the web
   10    10 
   11    11 In order to know how a native HTML `<icon>` element could work, we should look
   12    12 at existing solutions, as well as their problems and benefits.
@@ -37,7 +37,7 @@ SVG allows to style multi-colored icons with CSS. However, knowledge of image
   37    37 internals is required for that. The accessibility with these is better, but
   38    38 still far from perfect.
   39    39 
   40    -1 # Standalone vs. Presentational
   -1    40 ## Standalone vs. Presentational
   41    41 
   42    42 In my experience, there are two distinct usecases for icons: Sometimes icons
   43    43 are used with a label. Icons like this are not strictly necessary, but they
@@ -77,7 +77,7 @@ The HTML that is currently required for this is a bit redundant:
   77    77 </button>
   78    78 ```
   79    79 
   80    -1 # My proposal
   -1    80 ## My proposal
   81    81 
   82    82 I propose to add something like this to HTML:
   83    83 
@@ -107,7 +107,7 @@ There is just one restriction for privacy reasons: Web pages should not be able
  107   107 to find out which users personalize their icons. For that reason, all icons
  108   108 must be square.
  109   109 
  110    -1 # Open questions
   -1   110 ## Open questions
  111   111 
  112   112 -	How does branding/personalization work exactly? It somewhat works with fonts,
  113   113 	but that's still far from perfect.
@@ -119,7 +119,7 @@ must be square.
  119   119 	can new icons be added to the registry without the hassle of a full
  120   120 	standardization process?
  121   121 
  122    -1 # Conclusion
   -1   122 ## Conclusion
  123   123 
  124   124 Icons are used literally everywhere. Adding them to HTML itself would allow to
  125   125 make life easier for web developers at the same time as improving

diff --git a/_content/posts/2018-01-14-consensus-meetings/index.md b/_content/posts/2018-01-14-consensus-meetings/index.md

@@ -6,7 +6,7 @@ There are meetings that are not ineffective. I have been in some. Those were
    6     6 the ones where everyone involved knew some rules. These rules are not black
    7     7 magic, but they are also not all that easy to explain. Still, I will try:
    8     8 
    9    -1 # Value the social aspects
   -1     9 ## Value the social aspects
   10    10 
   11    11 A meeting of the kind I am talking about mainly exists to make decisions. But
   12    12 it is also one of the rare occasions where your team comes together. It is a
@@ -22,12 +22,12 @@ decision as fast as possible?" But I think you should allow yourself to get
   22    22 side-tracked sometimes. Get to know each other and grow as a team. This will
   23    23 greatly improve things in the long run.
   24    24 
   25    -1 # Stick to the topic
   -1    25 ## Stick to the topic
   26    26 
   27    27 This one is obvious and I will not waste too much time with it: Contrary to what
   28    28 I said before, you should of course always try to stick to the topic.
   29    29 
   30    -1 # Decide by consensus
   -1    30 ## Decide by consensus
   31    31 
   32    32 Before I had experience with consensus-based decisions, I thought it was a
   33    33 grossly ineffective method. It turns out the exact opposite is true. The
@@ -51,7 +51,7 @@ Simple as that.
   51    51 A more detailed description of the process can be found in
   52    52 [RFC7282](https://tools.ietf.org/html/rfc7282).
   53    53 
   54    -1 # Be aware of common fallacies
   -1    54 ## Be aware of common fallacies
   55    55 
   56    56 The biggest issue with consensus-based decisions is that they are susceptible
   57    57 to social forces. You should be very critical of your position in the team. If
@@ -73,7 +73,7 @@ decision, i.e. leave everything as it currently is. Maybe this is the option
   73    73 you all can agree on. Or maybe it is bad enough for everyone to compromise on
   74    74 something else.
   75    75 
   76    -1 # Just do it
   -1    76 ## Just do it
   77    77 
   78    78 I honestly believe that if you follow these few rules you will have great
   79    79 meetings. Of course, this requires that everyone involved knows about them.

diff --git a/_content/posts/2018-05-28-zen/index.md b/_content/posts/2018-05-28-zen/index.md

@@ -16,7 +16,7 @@ pretense to nerd about philosophy for hundreds of pages.  But where Sophie
   16    16 explores the history of western philosophy, Pirsig mostly writes about his own
   17    17 ideas.
   18    18 
   19    -1 # Content
   -1    19 ## Content
   20    20 
   21    21 > The study of the art of motorcycle maintenance is really a miniature study of
   22    22 > the art of rationality itself. Working on a motorcycle, working well, caring,
@@ -57,7 +57,7 @@ by Donne Haraway and especially [agential
   57    57 cuts](https://en.wikipedia.org/wiki/Karen_Barad#Agential_realism) by Karen
   58    58 Barad.
   59    59 
   60    -1 # Conclusion
   -1    60 ## Conclusion
   61    61 
   62    62 > The real cycle you're working on is a cycle called yourself. The machine that
   63    63 > appears to be "out there" and the person that appears to be "in here" are not

diff --git a/_content/posts/2018-10-28-aria-quirks/index.md b/_content/posts/2018-10-28-aria-quirks/index.md

@@ -12,7 +12,7 @@ opinion on any of these, I would love to hear from you!
   12    12 
   13    13 [1]: http://getbootstrap.com/docs/4.1/components/
   14    14 
   15    -1 # Building my own assistive technology
   -1    15 ## Building my own assistive technology
   16    16 
   17    17 Most screen readers let you navigate along the headings, links, or landmarks in
   18    18 a page. Since visual scanning is impossible for most visually impaired users,
@@ -34,7 +34,7 @@ any bugs, please make sure to [report them][3].
   34    34 [2]: https://addons.mozilla.org/de/firefox/addon/a11y-outline/
   35    35 [3]: https://github.com/xi/a11y-outline/issues
   36    36 
   37    -1 # ARIA primer
   -1    37 ## ARIA primer
   38    38 
   39    39 So, what is this ARIA thing?
   40    40 
@@ -66,12 +66,12 @@ operating systems. The layers in between are defined in different specs:
   66    66 -	The mapping between ARIA and OS APIs is defined in the [Core Accessibility API Mappings (Core-AAM)](https://www.w3.org/TR/core-aam-1.1/).
   67    67 -	Some additional parts have been split out, e.g. the [Accessible Name and Description Computation](https://www.w3.org/TR/accname-1.1/).
   68    68 
   69    -1 # Quirks
   -1    69 ## Quirks
   70    70 
   71    71 Now with the introduction out of the way, let's get to the weird stuff. We
   72    72 start slow though.
   73    73 
   74    -1 ## Landmarks
   -1    74 ### Landmarks
   75    75 
   76    76 Landmark is a category of roles. Here is a typical layout for a page:
   77    77 
@@ -126,7 +126,7 @@ Forms, on the other hand, only become landmarks if they have an explicit label:
  126   126 </form>
  127   127 ```
  128   128 
  129    -1 ## Accessible name calculation
   -1   129 ### Accessible name calculation
  130   130 
  131   131 Each element has a name and description. The algorithem to calculate them is
  132   132 crazy complicated as it contains recursion and tons of special cases. My own
@@ -218,7 +218,7 @@ If I follow the spec to the word the name for the select element should be
  218   218 sure this is not intended. Probably only the selected option should be
  219   219 included.
  220   220 
  221    -1 ## CSS is kinda relevant
   -1   221 ### CSS is kinda relevant
  222   222 
  223   223 Ok, this is web 1x1, right? HTML is for content, CSS is for presentation, JS is
  224   224 for behavior. So the ARIA semantics should surely not be influenced by CSS,
@@ -269,7 +269,7 @@ when calculating names.
  269   269 <p><em>un</em>subscribe</p>  <!-- unsubscribe -->
  270   270 ```
  271   271 
  272    -1 ## HTML-AAM overrides other specs
   -1   272 ### HTML-AAM overrides other specs
  273   273 
  274   274 Remember how I wrote about this nice hierarchy in the beginning? It was HTML -
  275   275 HTML-AAM - ARIA - Core-AAM - OS APIs. Well …, that is not actually true.
@@ -287,7 +287,7 @@ are completely different than the default algorithm. In this case, the
  287   287 otherwise rarely used `title` attribute wins. The `hidden` flag is simply
  288   288 ignored.
  289   289 
  290    -1 ## Conflicts
   -1   290 ### Conflicts
  291   291 
  292   292 Ready for the final quirk? In my opionion this is the worst one and also the
  293   293 one that is probably the hardest to fix.
@@ -309,7 +309,7 @@ documented exceptions:
  309   309 > same implicit semantic.
  310   310 > — <https://www.w3.org/TR/core-aam-1.1/#mapping_conflicts>
  311   311 
  312    -1 # Conclusion
   -1   312 ## Conclusion
  313   313 
  314   314 ARIA contains some unexpected bits and even some bugs that result from high
  315   315 complexity. Maybe this complexity could be reduced in some places.

diff --git a/_content/posts/2019-01-13-visual/index.md b/_content/posts/2019-01-13-visual/index.md

@@ -7,7 +7,7 @@ For some reason, we treat sight special. We say "I see" when we really mean "I
    7     7 understand". [Bret Victor](http://worrydream.com/#!/LearnableProgramming) even
    8     8 claims that "People understand what they can see". Why is that?
    9     9 
   10    -1 # Senses
   -1    10 ## Senses
   11    11 
   12    12 First, it is important to note that sight is especially well developed in
   13    13 humans compared to other mammals. Dogs for example have an advanced sense of
@@ -33,7 +33,7 @@ required to pass them on orally from generation to generation. Writing them
   33    33 down was ultimately the better way to record information. (Today, we can also
   34    34 record sounds. But that is a comparatively recent invention.)
   35    35 
   36    -1 # Text
   -1    36 ## Text
   37    37 
   38    38 Maybe comparing sight to other senses is not the right approach: I think that
   39    39 what Bret Victor enjoys about seeing a diagram is that it is more intuitive to
@@ -57,7 +57,7 @@ trends are worrisome. Today it is hard to find a complicated text that is not
   57    57 "lightened up" by some image. I fear that these graphics are intuitive to a
   58    58 point where you *believe* to understand more than actually understanding.
   59    59 
   60    -1 # Conclusion
   -1    60 ## Conclusion
   61    61 
   62    62 After reading a lot about the topic I now have a better understanding of why
   63    63 visuals are so important in web design. But I still think that we should be

diff --git a/_content/posts/2019-05-02-debian-packages/index.md b/_content/posts/2019-05-02-debian-packages/index.md

@@ -4,7 +4,7 @@ passes all lintian checks and could be included in the official repositories.
    4     4 If you just want to use the package for yourself, the process is not actually
    5     5 that hard.
    6     6 
    7    -1 # Why should I create a debian package?
   -1     7 ## Why should I create a debian package?
    8     8 
    9     9 If you are using debian or any of its derivatives such as ubuntu or mint, you
   10    10 typically install software on your system as debian packages using the `apt`
@@ -26,7 +26,7 @@ knows about both the files and dependencies and can remove them automatically.
   26    26 As an added benefit, you get an automatic update if your distribution starts
   27    27 packaging the software.
   28    28 
   29    -1 # The joy of meta-packages
   -1    29 ## The joy of meta-packages
   30    30 
   31    31 A special kind of package you may want to create are meta-packages. A
   32    32 meta-package is one that only defines dependencies and contains no files of its
@@ -39,7 +39,7 @@ everything else gets installed automatically. That way, the list of manually
   39    39 installed packages stays short and concise. Meta-packages are also great to
   40    40 manage build-dependencies for other packages.
   41    41 
   42    -1 # How to create a package
   -1    42 ## How to create a package
   43    43 
   44    44 So here is the tutorial:
   45    45 
@@ -63,7 +63,7 @@ Simple as that.
   63    63 
   64    64 You can install the package using `sudo apt install {filename}`.
   65    65 
   66    -1 # Taking the next step
   -1    66 ## Taking the next step
   67    67 
   68    68 Now that you have a simple package, there are some things you could look into
   69    69 to improve it:
@@ -78,7 +78,7 @@ to improve it:
   78    78 -	Instead of copying the files manually into the package folder, instruct `make
   79    79 	install` to do it automatically.
   80    80 
   81    -1 # Conclusion
   -1    81 ## Conclusion
   82    82 
   83    83 Creating debian packages is not so hard after all. It may not be as refined as
   84    84 the [`PKGBUILD` system in

diff --git a/_content/posts/2019-06-24-terminal-colors/index.md b/_content/posts/2019-06-24-terminal-colors/index.md

@@ -5,7 +5,7 @@ this:
    5     5 
    6     6 I tried to find out why that happens. This article is a summary of what I found.
    7     7 
    8    -1 # ANSI colors
   -1     8 ## ANSI colors
    9     9 
   10    10 Modern terminals can display 256 colors. But when talking about terminal color
   11    11 schemes, we talk about a set of 16 colors, known as ANSI colors.
@@ -29,7 +29,7 @@ bother to define which colors should be used together.
   29    29 
   30    30 So let's see how popular terminal themes handle this.
   31    31 
   32    -1 # Tango
   -1    32 ## Tango
   33    33 
   34    34 ![the tango color scheme](tango.png)
   35    35 
@@ -46,7 +46,7 @@ I am used to this theme and would like to stick with it. It is listed here as
   46    46 some kind of baseline. Later in the article, I will try to improve it using
   47    47 concepts from other themes.
   48    48 
   49    -1 # Solarized
   -1    49 ## Solarized
   50    50 
   51    51 ![solarized color scheme (dark mode)](solarized-dark.png)
   52    52 
@@ -89,7 +89,7 @@ of the bright colors with greys.
   89    89 So solarized is a mixed bag. I like its structured approach but don't agree
   90    90 with most of the design decisions.
   91    91 
   92    -1 # Gruvbox
   -1    92 ## Gruvbox
   93    93 
   94    94 ![gruvbox color scheme (dark mode)](gruvbox-dark.png)
   95    95 
@@ -126,7 +126,7 @@ the "black" color as background and the "bright white" color as foreground.
  126   126 That is not the case for solarized and yet another reason why application
  127   127 authors cannot rely on these colors.
  128   128 
  129    -1 # Tango with consistent lightness
   -1   129 ## Tango with consistent lightness
  130   130 
  131   131 Luckily, I am not trying to build a light theme, so many of the issues
  132   132 mentioned above don't directly affect me. But still, the only tangible advice I
@@ -167,7 +167,7 @@ adjusting the bright colors:
  167   167 
  168   168 ![a variant of tango with manual adjustments](tango-selective.png)
  169   169 
  170    -1 # Conclusion
   -1   170 ## Conclusion
  171   171 
  172   172 Honestly, I am not sure I found out anything. But I will try to cobble together
  173   173 some advice:
@@ -193,7 +193,7 @@ as motivation for this whole thing? After taking it I realized that I had
  193   193 forgotten to switch back to the original tango theme. So it was taken using the
  194   194 already improved version. That's how little has improved.
  195   195 
  196    -1 # One more fun idea
   -1   196 ## One more fun idea
  197   197 
  198   198 This is an idea I had that didn't really fit into the article:
  199   199 

diff --git a/_content/posts/2020-01-20-open-source/index.md b/_content/posts/2020-01-20-open-source/index.md

@@ -23,7 +23,7 @@ of different types of software projects. The categorization that I want to
   23    23 propose is about whether a software is meant to be generic and who its target
   24    24 audience is.
   25    25 
   26    -1 # Side projects
   -1    26 ## Side projects
   27    27 
   28    28 On the non-generic technical-user side of the spectrum are hobby projects.
   29    29 Things you do by yourself and for yourself. You get payed in fun and experience
@@ -36,7 +36,7 @@ it useful. I personally really like to look at existing attempts of solving a
   36    36 problem. I mostly don't end up using any of these projects, but I learn a lot
   37    37 from them anyways.
   38    38 
   39    -1 # Bespoke applications
   -1    39 ## Bespoke applications
   40    40 
   41    41 Companies need software for their internal processes. This software must be
   42    42 usable for non-technical users. Developers have no intrinsic motivation to
@@ -49,7 +49,7 @@ else might find it useful and maybe even contribute back some bug fixes. In
   49    49 addition, using GPL allows you to use GPL libraries. Choosing open source also
   50    50 tends to help with recruiting developers.
   51    51 
   52    -1 # Infrastructure
   -1    52 ## Infrastructure
   53    53 
   54    54 With the first two categories, publishing the code was a nice addition, but the
   55    55 software was not really meant to be used by anyone else. While these are
@@ -79,7 +79,7 @@ important a piece of infrastructure is, the more important it is that there is
   79    79 a clear governance model. If the US government provided the funding for
   80    80 openssl, would that have any influence on NSA backdoors?
   81    81 
   82    -1 # End-user applications
   -1    82 ## End-user applications
   83    83 
   84    84 Finally, on the generic end-user end of the spectrum we have projects
   85    85 such as firefox, libre office, gnome, or wordpress.
@@ -94,7 +94,7 @@ I honestly don't know where projects from this category get their funding from.
   94    94 I can just imagine that it is not simple. All the more reason to be impressed
   95    95 by the projects that do exist.
   96    96 
   97    -1 # Proprietary software
   -1    97 ## Proprietary software
   98    98 
   99    99 I talked a lot about the different categories of open source and their
  100   100 different benefits. But what about proprietary software?
@@ -115,7 +115,7 @@ there are semen-free cookies available for free.
  115   115 I understand that other people will associate secrecy and a high price with
  116   116 high quality. So this is totally subjective. But to me it feels shady.
  117   117 
  118    -1 # Price of work
   -1   118 ## Price of work
  119   119 
  120   120 Mark Tarver criticises that there is a culture of self-exploitation in open
  121   121 source, where people put in much more than they get out. This is definitely not
@@ -134,7 +134,7 @@ ways to fund small infrastructure projects is definitely helpful, the other
  134   134 approach to establish clear boundaries and go back to being a side project is
  135   135 equally valid.
  136   136 
  137    -1 # Conclusion
   -1   137 ## Conclusion
  138   138 
  139   139 I think the open source community is in a really great spot: We publish many
  140   140 side projects to learn from one another, we get paid to build bespoke

diff --git a/_content/posts/2020-05-16-pad/index.md b/_content/posts/2020-05-16-pad/index.md

@@ -38,7 +38,7 @@ that would otherwise be unintelligible.
   38    38 
   39    39 Long story short: I built my own plain-text pad.
   40    40 
   41    -1 # The Goal
   -1    41 ## The Goal
   42    42 
   43    43 The guiding principle had to be simplicity: I wanted to get 80% of
   44    44 functionality for 20% effort.
@@ -51,7 +51,7 @@ To take this further I was also willing to cut corners in terms of
   51    51 collaboration: My assumption was that concurrent edits in the same place are
   52    52 rare and that there is really no perfect way to handle them anyway.
   53    53 
   54    -1 # Implementation
   -1    54 ## Implementation
   55    55 
   56    56 I read the original [etherpad design
   57    57 document](https://github.com/ether/etherpad-lite/raw/master/doc/easysync/easysync-full-description.pdf)
@@ -105,7 +105,7 @@ change on conflict. As this happens quickly, users can react and re-apply their
  105   105 change manually. The big lesson here is that convergence is more important than
  106   106 the quality of the merge.
  107   107 
  108    -1 # Testing
   -1   108 ## Testing
  109   109 
  110   110 I created bots for testing that helped me find some bugs. But since many of my
  111   111 simplifications relied on assumptions about real-world usage I had to test with
@@ -115,7 +115,7 @@ When I was confident enough I asked some coworkers if we could use my pad
  115   115 for a real meeting. And what can I say. During the meeting I completely forgot
  116   116 that this was my new tool. It just worked.
  117   117 
  118    -1 # Conclusion
   -1   118 ## Conclusion
  119   119 
  120   120 So there it is. You can find the code at <https://git.ce9e.org/pad/> and a demo
  121   121 at <https://pad.ce9e.org/>. It ended up being ~220 lines of javascript. That is

diff --git a/_content/posts/2020-10-10-thunderbird/index.md b/_content/posts/2020-10-10-thunderbird/index.md

@@ -12,7 +12,7 @@ work!"
   12    12 I don't want to feel like it was all for nothing, at least I want to write
   13    13 down what I learned. So this is me rambling about some random software release.
   14    14 
   15    -1 # WebExtensions
   -1    15 ## WebExtensions
   16    16 
   17    17 So let's start at the beginning. What was this release all about? If you look
   18    18 through the [official release notes][1] it sound like the focus was on UI
@@ -29,7 +29,7 @@ completely, and some may not be possible with the new APIs at all. But in
   29    29 contrast to the UI changes described above I can see a lot of value in the
   30    30 refactoring work that is being done, even if it causes me some trouble.
   31    31 
   32    -1 # Builtin PGP support
   -1    32 ## Builtin PGP support
   33    33 
   34    34 One of the most popular extensions that was not going to be supported was
   35    35 [Enigmail][3]. The Thunderbird developers of course would never dare to release
@@ -85,7 +85,7 @@ You can also vote for this UI on the [feature request][8] I created.
   85    85 (Full disclosure: I am not a genius designer. I just copied what enigmal had
   86    86 done before.)
   87    87 
   88    -1 # My own extension
   -1    88 ## My own extension
   89    89 
   90    90 All that was the easy part, the part where I can simply vent about bad design
   91    91 without any responsibility of my own. This part now is about an extension I
@@ -124,7 +124,7 @@ So the big question is what will happen to Experiments in the future: Is this
  124   124 just a temporary playground to test different interfaces until we settle on a
  125   125 common set? Or will it be around indefinitely to support fringe use cases?
  126   126 
  127    -1 # Conclusion
   -1   127 ## Conclusion
  128   128 
  129   129 This is not really about bad design because I think with all the refactoring
  130   130 and UI cleanup as well as the built-in PGP support Thunderbird 78 is the best

diff --git a/_content/posts/2020-11-21-file-type-101/index.md b/_content/posts/2020-11-21-file-type-101/index.md

@@ -19,7 +19,7 @@ file types. So this is what this article is about. After reading this you will
   19    19 have a basic understanding of what any file is and how you might be able to
   20    20 interact with it.
   21    21 
   22    -1 # A file is not a program
   -1    22 ## A file is not a program
   23    23 
   24    24 Before I get into it, I have to clear up a common misconception:
   25    25 
@@ -39,7 +39,7 @@ files.
   39    39 
   40    40 With that out of the way, let's get to the actual files.
   41    41 
   42    -1 # Text files
   -1    42 ## Text files
   43    43 
   44    44 You probably already know that files just consist of ones and zeroes, also
   45    45 called *bits*. How these bits are interpreted depends on the specific type,
@@ -70,7 +70,7 @@ If you come across a file which you don't know it is often a good idea to look
   70    70 at it in a text editor. If the file happens to contain text, you can read it
   71    71 and maybe understand enough to know what to do next.
   72    72 
   73    -1 # XML
   -1    73 ## XML
   74    74 
   75    75 Mapping bits to characters already gives us some structure, but apparently not
   76    76 enough. So people have invented different formats on top of that. Probably the
@@ -96,7 +96,7 @@ brackets.
   96    96 XML is used virtually everywhere. For example: Every website is essentially
   97    97 just an XML file.
   98    98 
   99    -1 # ZIP
   -1    99 ## ZIP
  100   100 
  101   101 Text files are great because they are much easier to read compared to a stream
  102   102 of ones and zeroes. However, that comes at the price of being less efficient.
@@ -113,7 +113,7 @@ This is actually how many file types work these days. For example, try changing
  113   113 the file extension of any MS Office file to `.zip`. You can now unpack it and
  114   114 see what it contains: You guessed it, a bunch of XML files!
  115   115 
  116    -1 # Conclusion
   -1   116 ## Conclusion
  117   117 
  118   118 Of course there are a lot more file types. But text files and ZIP alone already
  119   119 cover a lot of ground.

diff --git a/_content/posts/2020-12-28-wayland-wm/index.md b/_content/posts/2020-12-28-wayland-wm/index.md

@@ -2,7 +2,7 @@ If a voice in your had is currently screaming "THERE ARE NO WINDOW MANAGERS IN
    2     2 WAYLAND, THEY ARE CALLED COMPOSITORS" you swallowed the bait. That is exactly
    3     3 what I want to write about. But let me start at the beginning:
    4     4 
    5    -1 # A short history of wayland
   -1     5 ## A short history of wayland
    6     6 
    7     7 For the last 30-odd years graphics on Unix were dominated by X11. In 2008 the
    8     8 people who maintained X11 declared that for the good of the project, starting
@@ -14,7 +14,7 @@ was looking good. Fedora uses wayland by default since 2016. But most other
   14    14 distros in 2020 still use an X11 server, which at this point is [largly
   15    15 unmaintained](https://news.ycombinator.com/item?id=24884988). What went wrong?
   16    16 
   17    -1 # The modular X11 desktop
   -1    17 ## The modular X11 desktop
   18    18 
   19    19 X11 was about painting pixels to the screen. But it also provided APIs
   20    20 like [EWMH](https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html)
@@ -39,7 +39,7 @@ standardized APIs. If you want to port your desktop to wayland, you have to
   39    39 replace everything all at once. That might be possible for Gnome and KDE, but
   40    40 not for the ecosystem of modular components.
   41    41 
   42    -1 # The wlroots project
   -1    42 ## The wlroots project
   43    43 
   44    44 This decision by the wayland maintainers did not neccesarily mean the end of
   45    45 the modular desktop though. Someone else could step in and define the necessary
@@ -56,7 +56,7 @@ repo, but there is little progress. And even though there are many
   56    56 wlroots-based compositors, the only one ready for production is
   57    57 [sway](https://github.com/swaywm/sway).
   58    58 
   59    -1 # Sway
   -1    59 ## Sway
   60    60 
   61    61 About once a year I look at wayland, mess around a little, get frustrated, and
   62    62 soon decide that I should wait another year. This year around I tried sway,
@@ -79,7 +79,7 @@ but none of these is really in a usable state. I looked at their code and
   79    79 quickly decided that writing one myself was also out of the question. So what
   80    80 could I do?
   81    81 
   82    -1 # Writing a wayland window manager
   -1    82 ## Writing a wayland window manager
   83    83 
   84    84 I had already created a toy X11 window manager (based on
   85    85 [dwm](https://dwm.suckless.org/)) in the past. It is not actually that hard:
@@ -187,7 +187,7 @@ if __name__ == '__main__':
  187   187     con.main()
  188   188 ```
  189   189 
  190    -1 # Conclusion
   -1   190 ## Conclusion
  191   191 
  192   192 Wayland is the future and outside of the big desktop environments, sway is the
  193   193 only viable option right now. So if, like me, you want to use wayland but don't

diff --git a/_content/posts/2021-04-03-zero-cost-optimizations/index.md b/_content/posts/2021-04-03-zero-cost-optimizations/index.md

@@ -5,7 +5,7 @@ practically zero. So why not do them?
    5     5 In this post I want to share some thoughts about the structure of this kind
    6     6 of optimization.
    7     7 
    8    -1 # Examples
   -1     8 ## Examples
    9     9 
   10    10 That sounds very abstract, so what do I mean by this?
   11    11 
@@ -23,12 +23,12 @@ One example from another area of life would be veganism. For the largest part
   23    23 it is healthier, kinder, and more sustainable than eating meat. There is no
   24    24 extra effort involved. I see no reason against it.
   25    25 
   26    -1 # Counter arguments
   -1    26 ## Counter arguments
   27    27 
   28    28 Obviously not all people value accessibility, code styling and veganism. I want
   29    29 to look at some common counter arguments:
   30    30 
   31    -1 ## You ain't gonna need it
   -1    31 ### You ain't gonna need it
   32    32 
   33    33 [YAGNI](http://c2.com/xp/YouArentGonnaNeedIt.html) is a reminder against
   34    34 feature creep. Even if you think you will need a feature, don't implement it
@@ -37,7 +37,7 @@ situations. However, all examples I mentioned were about doing a thing
   37    37 *differently* rather than adding something new on top. So I don't think it
   38    38 applies.
   39    39 
   40    -1 ## Effective altruism
   -1    40 ### Effective altruism
   41    41 
   42    42 [Effective
   43    43 altruism](https://www.jefftk.com/p/effective-altruism-and-everyday-decisions)
@@ -51,7 +51,7 @@ Still, I see no reason not to do them. I would rephrase this critizism as:
   51    51 "Don't spend time arguing about it, just do it". (I am aware of the irony of me
   52    52 writing a blog post about this topic. We all have our faults.)
   53    53 
   54    -1 ## Virtue signalling
   -1    54 ### Virtue signalling
   55    55 
   56    56 [Virtue signalling](https://www.urbandictionary.com/define.php?term=Virtue%20Signalling)
   57    57 is the allegation that people do zero cost optimizations not for their benefits
@@ -66,7 +66,7 @@ not communicate"](https://en.wikipedia.org/wiki/Paul_Watzlawick). I would argue
   66    66 that this form of communication is even useful in most cases. It is good to
   67    67 know whether the person I talk to actually knows and cares about the topic.
   68    68 
   69    -1 # Habits and teams
   -1    69 ## Habits and teams
   70    70 
   71    71 When I say these optimizations come at zero cost, that is only true for the
   72    72 long term. When you are just starting you may need to change your habits, and
@@ -81,7 +81,7 @@ As you usually communicate with different people, you need to have some degree
   81    81 of flexibility in your habits. If you over-optimize, you will have a hard time
   82    82 fitting in.
   83    83 
   84    -1 # Conclusion
   -1    84 ## Conclusion
   85    85 
   86    86 Zero cost optimizations, also called "virtue signalling", are efficient but
   87    87 ineffective actions based on habits. Arguing about them is not worth the time.

diff --git a/_content/posts/2021-08-20-linux-service-architecture/index.md b/_content/posts/2021-08-20-linux-service-architecture/index.md

@@ -8,7 +8,7 @@ Maybe I am totally mistaken and what I want to point out is clear as daylight
    8     8 to everyone but me. But I have never seen it spelled out. So I will attempt to
    9     9 do the spelling.
   10    10 
   11    -1 # Chapter 1: Traditional Unix
   -1    11 ## Chapter 1: Traditional Unix
   12    12 
   13    13 A process on a unix system traditionally acts as a proxy for the user. If I use
   14    14 some software, that software can do anything that I can do. And if I use some
@@ -18,7 +18,7 @@ There have been attempts at more fine-grained access control with systems such
   18    18 as SELinux or AppArmor, but writing correct configuration for them is tedious.
   19    19 So most processes run unconfined.
   20    20 
   21    -1 # Chapter 2: The rise of system services
   -1    21 ## Chapter 2: The rise of system services
   22    22 
   23    23 Running software as root is dangerous, so we want to avoid that. Additionally,
   24    24 especially on single-user systems, it does not make much sense to require root
@@ -49,7 +49,7 @@ would cause many heated discussion throughout the next years.
   49    49 In today's linux there are few reasons to ever use `sudo`. (At least in theory,
   50    50 because I for one still use `mount` over `udiskctl` and `apt` over `pkcon`.)
   51    51 
   52    -1 # Chapter 3: Same concept, different name
   -1    52 ## Chapter 3: Same concept, different name
   53    53 
   54    54 After the threat of software running as root was banned, people quickly
   55    55 realized that running as regular users also comes with risks. A tame-looking
@@ -90,7 +90,7 @@ Running untrusted code feels much less scary when it is sandboxed and
   90    90 applications need stable API to program against, so this whole idea is closely
   91    91 related to that of portals.
   92    92 
   93    -1 ## Chapter 4: What it all means
   -1    93 ### Chapter 4: What it all means
   94    94 
   95    95 I think I have now mentioned every single hot linux topic from the past 15
   96    96 years at least once. And everything is connected!

diff --git a/_content/posts/2022-02-20-minimalism/index.md b/_content/posts/2022-02-20-minimalism/index.md

@@ -2,7 +2,7 @@ Ok, this is going to be a rambling mess. There are some things I want to write
    2     2 down and I don't yet know how to put the different threads together. So let's
    3     3 untangle that mess.
    4     4 
    5    -1 # I am not yet sure where this is going
   -1     5 ## I am not yet sure where this is going
    6     6 
    7     7 The first thread is about the linux desktop community. Compared to others, this
    8     8 community is tiny. Shell scripting for example is a much bigger community
@@ -23,7 +23,7 @@ just a function of the size of the community. On any given web topic you will
   23    23 likely find 10 helpful blog posts. For linux desktop stuff you are lucky if you
   24    24 find anything relevant at all.
   25    25 
   26    -1 # A lot of quotes pushed into a single section
   -1    26 ## A lot of quotes pushed into a single section
   27    27 
   28    28 Which brings us to the second thread: Why should anyone even want to build
   29    29 their own desktop? Why not stick with gnome or KDE or whathaveyou?
@@ -56,7 +56,7 @@ an important part of the journey.
   56    56 > together.
   57    57 > — Robert M. Pirsig, Zen and the Art of Motorcycle Maintenance
   58    58 
   59    -1 # Information walks into a bar
   -1    59 ## Information walks into a bar
   60    60 
   61    61 The third thread is about displaying up-to-date information in a status bar. In
   62    62 order for it to really be live, we need to push new information into the UI as
@@ -75,7 +75,7 @@ unicode symbols to get some more interesting graphics. With
   75    75 [i3blocks](https://github.com/vivien/i3blocks) and similar projects there is
   76    76 even an ecosystem of modular tools that can generate input for these bars.
   77    77 
   78    -1 # How did I get here?
   -1    78 ## How did I get here?
   79    79 
   80    80 The next thread is about the people in this community. And this is where it
   81    81 gets weird.
@@ -111,7 +111,7 @@ vim and dwm and how the jews are using mainstream media to brainwash us.
  111   111 
  112   112 So yeah, this community is full of racists.
  113   113 
  114    -1 # Let's quickly talk about something else
   -1   114 ## Let's quickly talk about something else
  115   115 
  116   116 While using pipes is obviously the much cleaner option, most mainstream
  117   117 applications broadcast their status via dbus. So I did what seemed obvious and
@@ -121,7 +121,7 @@ display those.
  121   121 
  122   122 The result is available on github: <https://github.com/xi/polybar-status-indicators>
  123   123 
  124    -1 # I have no clue how to end this
   -1   124 ## I have no clue how to end this
  125   125 
  126   126 I really really like minimalist software. I seem to share this
  127   127 longing for purity with fascists. That's fucked up.

diff --git a/_content/posts/2022-06-25-hard-work/index.md b/_content/posts/2022-06-25-hard-work/index.md

@@ -12,7 +12,7 @@ David R. MacIver writes:
   12    12 I found that distinction interesting to reflect about my work, so I will try to
   13    13 add some of my thoughts to the discussion.
   14    14 
   15    -1 # The problem with automation
   -1    15 ## The problem with automation
   16    16 
   17    17 My job consists mostly of identifying areas where people in the organisation
   18    18 have to do hard work and finding better ways to do that.
@@ -51,7 +51,7 @@ best choice in every case. While reflecting on this, I realize that I sometimes
   51    51 focus too much on eliminating hard work and do not actually consider the
   52    52 downsides of the alternatives.
   53    53 
   54    -1 # A better option
   -1    54 ## A better option
   55    55 
   56    56 Now you may be asking: "Why are there even numbers on paper?" And I think that
   57    57 is exactly the right question to ask here. Maybe we can just talk to the other

diff --git a/_content/posts/2022-09-10-contrast-algorithms/index.md b/_content/posts/2022-09-10-contrast-algorithms/index.md

@@ -6,7 +6,7 @@ I don't want to pick on the color.js authors specifically. They are generally
    6     6 doing an awesome job. This documentation just happens to aggregate many of the
    7     7 claims that can be found throughout the internet.
    8     8 
    9    -1 # The many faces of Weber contrast
   -1     9 ## The many faces of Weber contrast
   10    10 
   11    11 Let's start with some fractions.
   12    12 
@@ -55,7 +55,7 @@ Admittedly, these formulas are not exactly the same. But I cannot see how you
   55    55 can say that simple contrast is unfit for real-world use and not say something
   56    56 similar about the others.
   57    57 
   58    -1 # Equivalence of contrast formulas
   -1    58 ## Equivalence of contrast formulas
   59    59 
   60    60 I want to try to formalize this notion of "similarity" between different
   61    61 formulas.
@@ -83,7 +83,7 @@ function would have to be linear and Weber would not be equivalent to Simple
   83    83 contrast. I do think this stricter definition has merit in some cases, but I
   84    84 will work with the weaker definition in this post.
   85    85 
   86    -1 # Lightness difference
   -1    86 ## Lightness difference
   87    87 
   88    88 The authors also mention lightness difference `Lmax -
   89    89 Lmin` as a way to calculate contrast:
@@ -110,12 +110,12 @@ claims that the other contrast algorithms are not based on perceptually uniform
  110   110 lightness difference and that simple contrast does not consider the logarithmic
  111   111 response characteristics of the human eye are bogus.
  112   112 
  113    -1 # APCA
   -1   113 ## APCA
  114   114 
  115   115 The final contrast formula mentioned in the color.js documentation is APCA. If
  116   116 you are interested in that I can refer you to my [detailed analysis][3].
  117   117 
  118    -1 # Conclusion
   -1   118 ## Conclusion
  119   119 
  120   120 The main takeaway is that simple contrast (and therefore WCAG 2.1) is not as
  121   121 bad as some people make it sound. It *is* based on a difference of perceptual

diff --git a/_content/posts/2022-12-03-my-window-manager-setup/index.md b/_content/posts/2022-12-03-my-window-manager-setup/index.md

@@ -2,7 +2,7 @@ I am still on X11 because I haven't yet found the right wayland setup for me.
    2     2 In this process, I had to take a good look at my current X11 setup. I was
    3     3 surprised what I found.
    4     4 
    5    -1 # My current setup
   -1     5 ## My current setup
    6     6 
    7     7 I usually have all windows maximized, so only a single window is visible at a
    8     8 time. (I also only have a single screen.) If I want to move a window across the
@@ -43,7 +43,7 @@ browser   `Ctrl-t`        `Ctrl-w`  `Ctrl-PageUp|PageDown`
   43    43 terminal  `Ctrl-Shift-t`  `Ctrl-d`  `Ctrl-PageUp|PageDown`
   44    44 vim       `:tabnew`       `:wq`     `Ctrl-Alt-PageUp|PageDown`
   45    45 
   46    -1 # How common is this?
   -1    46 ## How common is this?
   47    47 
   48    48 I believe this is not too exotic. I pretty much stayed with the defaults and
   49    49 the shortcuts like `Alt-Tab` or `Alt-F4` haven't really changed since I started
@@ -61,7 +61,7 @@ issue with maximize-by-default is that dialogs should actuall not be maximized,
   61    61 and window managers often have a hard time telling them apart. I am sure most
   62    62 people who use tiling window managers can relate.
   63    63 
   64    -1 # Consistency
   -1    64 ## Consistency
   65    65 
   66    66 What was shocking to me about this analysis was how inconsistent this all was.
   67    67 Not just are there 5 different window managers, they all use different
@@ -88,7 +88,7 @@ the browser, I can re-open the last recently closed tab. By forcing all these
   88    88 levels into a single window manager I would loose those small but important
   89    89 features.
   90    90 
   91    -1 # Keyboard usability
   -1    91 ## Keyboard usability
   92    92 
   93    93 One downside I definitely see in my current approach is that it requires a lot
   94    94 of different keys. `PageUp` and `PageDown` are not easy to reach on many
@@ -98,7 +98,7 @@ two devices, so I constantly have to readjust. Also, the heavy use of modifier
   98    98 keys makes it hard to use these shortcuts with a single hand, which might
   99    99 become an accessibility concern.
  100   100 
  101    -1 # Why not use tiling?
   -1   101 ## Why not use tiling?
  102   102 
  103   103 Displaying two windows side by side works on a stacking window managers, but it
  104   104 also has its flaws:
@@ -119,7 +119,7 @@ at all common there.
  119   119 Tiling window managers might have benefits for my use case, but so far there
  120   120 was no compelling reason to switch.
  121   121 
  122    -1 # Conclusion
   -1   122 ## Conclusion
  123   123 
  124   124 I took a good look at my window management setup and found that is messy, but
  125   125 sticks with defaults and works well.

diff --git a/_content/posts/2023-01-15-state-of-wayland/index.md b/_content/posts/2023-01-15-state-of-wayland/index.md

@@ -12,7 +12,7 @@ Please do not read this as a criticism of wayland as a whole. I understand that
   12    12 my use case may not be super common. These are just my personal notes on how
   13    13 well wayland works *for me*.
   14    14 
   15    -1 # The setup
   -1    15 ## The setup
   16    16 
   17    17 My OS is Debian Bookworm, so all software is in the version that is included
   18    18 with that OS.
@@ -26,7 +26,7 @@ sway-bar with a custom status script. In addition there are several smaller
   26    26 tools that are somewhat needed for a complete desktop: swayidle, swaylock,
   27    27 grim, slurp, wl-clipboard, and xdg-desktop-portal-wlr.
   28    28 
   29    -1 # What improved?
   -1    29 ## What improved?
   30    30 
   31    31 -	Last time I had major issues with blurry fonts because I did not manage to
   32    32 	configure antialiasing correctly. This time around, `gsettings set
@@ -60,7 +60,7 @@ grim, slurp, wl-clipboard, and xdg-desktop-portal-wlr.
   60    60 	than that the migration to gtk3 seems to be completed. So lets start porting
   61    61 	everything to gtk4 now!
   62    62 
   63    -1 # What needs more work?
   -1    63 ## What needs more work?
   64    64 
   65    65 -	GUI applications that run as root, such as gparted or synaptic, fail to
   66    66 	start. AFAIU, this is expected because of the stricter security model in
@@ -115,7 +115,7 @@ grim, slurp, wl-clipboard, and xdg-desktop-portal-wlr.
  115   115 		already implemented in libinput and gtk4, but it [will not be backported to
  116   116 		gtk3](https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3454#note_1426517).
  117   117 
  118    -1 # Conclusion
   -1   118 ## Conclusion
  119   119 
  120   120 So there you have it. 14 years after the initial wayland release we do have a
  121   121 usable desktop experience. Unfortunately, there are still gaping holes.

diff --git a/_content/posts/2023-01-29-python-async-loops/index.md b/_content/posts/2023-01-29-python-async-loops/index.md

@@ -18,12 +18,12 @@ enjoy accompanying me on that journey.
   18    18 If you are interested, all eight implementations are available on
   19    19 [github](https://github.com/xi/python_async_loops).
   20    20 
   21    -1 # Setup
   -1    21 ## Setup
   22    22 
   23    23 The following script outputs random numbers at random intervals:
   24    24 
   25    25 ```bash
   26    -1 #!/bin/bash
   -1    26 ##!/bin/bash
   27    27 while true; do
   28    28     sleep $(($RANDOM % 5))
   29    29     echo $RANDOM
@@ -85,7 +85,7 @@ def render():
   85    85 
   86    86 With these basics out of the way, we can start with the loop itself.
   87    87 
   88    -1 # Implementation 1: Blocking Loop
   -1    88 ## Implementation 1: Blocking Loop
   89    89 
   90    90 Putting it all together we get our first implementation: The blocking loop:
   91    91 
@@ -143,7 +143,7 @@ In this version, `reader.read_line()` will block until data is available. So it
  143   143 will first wait for data from `proc1`, then wait for data from `proc2`, then
  144   144 render, repeat. This is not really async yet.
  145   145 
  146    -1 # Implementation 2: Busy Loop
   -1   146 ## Implementation 2: Busy Loop
  147   147 
  148   148 ```python
  149   149 import fcntl
@@ -174,7 +174,7 @@ get stuck on a blocking read. However, this loop will just keep trying and
  174   174 fully saturate the CPU. This is called a busy loop and obviously not what we
  175   175 want.
  176   176 
  177    -1 # Implementation 3: Sleepy Loop
   -1   177 ## Implementation 3: Sleepy Loop
  178   178 
  179   179 ```python
  180   180 import time
@@ -199,7 +199,7 @@ quickly we introduce a very noticeable delay of 1 second. And if data arrives
  199   199 slowly we wake up much more often than would be needed. We can adjust the sleep
  200   200 duration to the specific case, but it will never be perfect.
  201   201 
  202    -1 # Implementation 4: Select Loop
   -1   202 ## Implementation 4: Select Loop
  203   203 
  204   204 ```python
  205   205 import selectors
@@ -233,7 +233,7 @@ So with this implementation we have our first *real* async loop, and from here
  233   233 on out we will stick with selectors and only restructure the code surrounding
  234   234 them.
  235   235 
  236    -1 # Implementation 5: Callback Loop
   -1   236 ## Implementation 5: Callback Loop
  237   237 
  238   238 ```python
  239   239 class Loop:
@@ -307,7 +307,7 @@ You can register files with callbacks that will be executed whenever the file
  307   307 is ready. There is also a much more sophisticated system for timeouts and
  308   308 intervals, similar to what you might know from JavaScript.
  309   309 
  310    -1 # Aside: Everything is a File
   -1   310 ## Aside: Everything is a File
  311   311 
  312   312 So far our loops can react to files and timeouts, but is that enough? My first
  313   313 hunch is that in unix, "everything is a file", so this should get us
@@ -355,12 +355,12 @@ pretty far. But let's take a closer look.
  355   355     tells you that the underlying file descriptor is empty, but there is still
  356   356     data available in the python buffer.
  357   357 
  358    -1 # Implementation 6: Generator Loop
   -1   358 ## Implementation 6: Generator Loop
  359   359 
  360   360 We are getting closer to asyncio, but there is still a lot of conceptual ground
  361   361 to cover. Before we get to async/await, we have to talk about generators.
  362   362 
  363    -1 ## Motivation
   -1   363 ### Motivation
  364   364 
  365   365 As I said in the introduction, I personally really like the callback approach.
  366   366 It is simple, just a selector and some callback functions. Compared to that I
@@ -419,7 +419,7 @@ share state, and do cleanup. The callback approach tries to get by without
  419   419 these benefits. The async/await approach instead tries to keep them by allowing
  420   420 to pause the execution of functions.
  421   421 
  422    -1 ## The yield expression
   -1   422 ### The yield expression
  423   423 
  424   424 The yield expression has been part of python since
  425   425 [PEP 255](https://peps.python.org/pep-0255/) (2001) and got extended
@@ -438,10 +438,10 @@ def foo():
  438   438 for x in foo():
  439   439     print(x)
  440   440 
  441    -1 # yielding 1
  442    -1 # 1
  443    -1 # yielding 2
  444    -1 # 2
   -1   441 ## yielding 1
   -1   442 ## 1
   -1   443 ## yielding 2
   -1   444 ## 2
  445   445 ```
  446   446 
  447   447 Another common use is to define context managers:
@@ -552,7 +552,7 @@ For a more in-depth discussion of generators I can recommend the [introduction
  552   552 to async/await by Brett
  553   553 Cannon](https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/).
  554   554 
  555    -1 ## The Loop
   -1   555 ### The Loop
  556   556 
  557   557 ```python
  558   558 import datetime
@@ -716,7 +716,7 @@ pass through the messages by using `yield from`.
  716   716 All this is mediated by `Task` objects which keep track of the conditions and
  717   717 state of generators.
  718   718 
  719    -1 # Implementation 7: async/await Loop
   -1   719 ## Implementation 7: async/await Loop
  720   720 
  721   721 From here it is a small step to async/await. Generators that are used for
  722   722 asynchronous execution have already been called "coroutines" in PEP 342. [PEP
@@ -892,7 +892,7 @@ async def amain():
  892   892 run(amain())
  893   893 ```
  894   894 
  895    -1 # Implementation 8: asyncio
   -1   895 ## Implementation 8: asyncio
  896   896 
  897   897 So which kinds of loop does asyncio use? After reading [PEP
  898   898 3156](https://peps.python.org/pep-3156/) I would say: That's complicated.
@@ -984,7 +984,7 @@ wrap loop callbacks.
  984   984 
  985   985 This approach works reasonably well. But I also see some issues with it.
  986   986 
  987    -1 ## Limited support for files
   -1   987 ### Limited support for files
  988   988 
  989   989 You may have noticed that I did not implement the full subprocess example this
  990   990 time. This is because asyncio's coroutine layer doesn't really support files.
@@ -994,7 +994,7 @@ callbacks are called every time data is available for reading. This disconnect
  994   994 can probably be bridged somehow, but this post is already long enough and I
  995   995 didn't want to go down yet another rabbit hole.
  996   996 
  997    -1 ## Futures are not a monad
   -1   997 ### Futures are not a monad
  998   998 
  999   999 If you know some JavaScript you have probably come across Promises. Promises
 1000  1000 are basically the JavaScript equivalent of Futures. However, they have a much
@@ -1032,7 +1032,7 @@ future2.add_done_callback(print_done)
 1032  1032 loop.run_until_complete(future2)
 1033  1033 ```
 1034  1034 
 1035    -1 ## Naming Confusion
   -1  1035 ### Naming Confusion
 1036  1036 
 1037  1037 So far we have "Coroutines", "Futures", and "Tasks". The asyncio documentation
 1038  1038 also uses the term "Awaitables" for anything that implements `__await__()`, so
@@ -1057,7 +1057,7 @@ final part could explain the low level plumbing for those people who want to
 1057  1057 dive deep. This is the only part that needs to mention terms like "Awaitable",
 1058  1058 "Task", or "Future".
 1059  1059 
 1060    -1 # Conclusion
   -1  1060 ## Conclusion
 1061  1061 
 1062  1062 These were eight different versions of asynchronous loops. I have certainly
 1063  1063 learned something. A bit about async primitives on linux and a lot about

diff --git a/_content/posts/2023-02-26-flow-relative-layout/index.md b/_content/posts/2023-02-26-flow-relative-layout/index.md

@@ -19,7 +19,7 @@ current writing mode. Unfortunately it is still in the draft stage. Some parts
   19    19 are already available in browsers, but some other parts are still [likely to
   20    20 change](https://www.w3.org/TR/css-logical-1/#issue-3d880eb1).
   21    21 
   22    -1 # What works
   -1    22 ## What works
   23    23 
   24    24 -	`block-size` and `inline-size`
   25    25 -	`margin-block-start`, `margin-inline-end`, …
@@ -33,7 +33,7 @@ change](https://www.w3.org/TR/css-logical-1/#issue-3d880eb1).
   33    33 
   34    34 Source: <https://www.w3.org/TR/CSS/#CR-exceptions> and <https://caniuse.com/css-logical-props>
   35    35 
   36    -1 # What doesn't work
   -1    36 ## What doesn't work
   37    37 
   38    38 -	[`float`](https://caniuse.com/mdn-css_properties_float_flow_relative_values)
   39    39 -	[`overflow-block|inline`](https://caniuse.com/mdn-css_properties_overflow-block)
@@ -49,7 +49,7 @@ with the layout but that do not adapt to the writing mode for a good reason:
   49    49 -	shadow offsets refer to physical directions
   50    50 -	…
   51    51 
   52    -1 # Recommendations
   -1    52 ## Recommendations
   53    53 
   54    54 There is no real reason to use `width` or `margin-bottom` anymore. Just get
   55    55 used to `inline-size` and `margin-block-end`.

diff --git a/_content/posts/2023-03-30-tui/index.md b/_content/posts/2023-03-30-tui/index.md

@@ -7,13 +7,13 @@ Because TUIs and CLIs are so different, switching between the two modes can be
    7     7 challenging. If you are not careful, the terminal ends up in an inconsistent
    8     8 state. But fear not! I will walk you through all the relevant steps.
    9     9 
   10    -1 # Enter and exit TUI mode
   -1    10 ## Enter and exit TUI mode
   11    11 
   12    12 Terminals do not have a dedicated TUI mode. Instead, there is a collection of
   13    13 options we can combine to get what we want. I will first describe each aspect
   14    14 and then provide a code example.
   15    15 
   16    -1 ## Disable line buffering
   -1    16 ### Disable line buffering
   17    17 
   18    18 In CLI mode, input is buffered and sent to `stdin` when the user presses the
   19    19 enter key. In TUI applications, we want to react to every key press
@@ -30,7 +30,7 @@ The python standard library also provides bindings for termios as well as the
   30    30 higher level `tty` module that allows us to easily disable line buffering using
   31    31 the `cbreak()` function.
   32    32 
   33    -1 ## Restore screen content on exit
   -1    33 ### Restore screen content on exit
   34    34 
   35    35 We do not want our TUI to mess up the terminal's scrollback buffer. So when we
   36    36 exit, we want to restore the screen content as it was before we started.
@@ -54,7 +54,7 @@ Switching to the alternate screen is `smcup` in terminfo and `\033[?1049h` in
   54    54 xterm. Switching back to the original screen is `rmcup` in terminfo and
   55    55 `\033[?1049l` in xterm.
   56    56 
   57    -1 ## Hide the cursor
   -1    57 ### Hide the cursor
   58    58 
   59    59 When typing in the command line, the cursor show us where the next typed
   60    60 character will be inserted. In many TUI applications, arbitrary regions of the
@@ -65,7 +65,7 @@ This can again be done using escape codes. Hiding the cursor is `civis` in
   65    65 terminfo and `\033[?25l` in xterm. Showing the cursor is `cnorm` in terminfo
   66    66 and `\033[?25h` in xterm.
   67    67 
   68    -1 ## Putting it all together
   -1    68 ### Putting it all together
   69    69 
   70    70 ```python
   71    71 import sys
@@ -92,14 +92,14 @@ run_mainloop()
   92    92 exit_tui()
   93    93 ```
   94    94 
   95    -1 # Handling exceptions
   -1    95 ## Handling exceptions
   96    96 
   97    97 The above code still has a major issue: When our mainloop raises an exception,
   98    98 the process ends without exiting TUI mode, so we end up with broken terminal.
   99    99 The fix in this case is simple though: Wrap the code in a `try … finally` block
  100   100 so the cleanup code is run even if there are exceptions.
  101   101 
  102    -1 # Handling `ctrl-z`
   -1   102 ## Handling `ctrl-z`
  103   103 
  104   104 You can stop any program in the terminal by pressing `ctrl-z`. That program
  105   105 will simply not do anything until you type `fg`. When we stop our TUI
@@ -148,7 +148,7 @@ Some things to note:
  148   148 -	The screen might have changed in the meantime, so it is best to do a fresh
  149   149 	render.
  150   150 
  151    -1 # Using context managers
   -1   151 ## Using context managers
  152   152 
  153   153 If you are like me, the code examples above scream *context manager*. This
  154   154 could look something like this:
@@ -202,7 +202,7 @@ i.e. we must be able to enter and exit it multiple times. This is the case
  202   202 here, but is not always guaranteed. For example, context managers that are
  203   203 created using the `@contextmanager` decorator are not reusable.
  204   204 
  205    -1 # Get terminal size
   -1   205 ## Get terminal size
  206   206 
  207   207 As the cherry on top, we should know how much space is available, e.g. to draw
  208   208 a bar that spans the complete width of the terminal. Python provides us with a
@@ -212,7 +212,7 @@ However, terminals can be resized. So you should also register a handler for
  212   212 `SIGWINCH` that gets the latest size and re-renders your application whenever
  213   213 the size changes.
  214   214 
  215    -1 # Conclusion
   -1   215 ## Conclusion
  216   216 
  217   217 There are many libraries that take care of all of this for you. But sometimes
  218   218 you run into issues anyway. You should now have all the tools to track down the

diff --git a/_content/posts/2023-09-28-mfa/index.md b/_content/posts/2023-09-28-mfa/index.md

@@ -10,7 +10,7 @@ old "passwords are bad and MFA is better" dance. I will still do the
   10    10 comparison, but only skim the boring parts and quickly move on to the
   11    11 (hopefully) more interesting details.
   12    12 
   13    -1 # Passwords
   -1    13 ## Passwords
   14    14 
   15    15 Passwords have been used for authentication for a long time, even though they have many issues:
   16    16 
@@ -23,13 +23,13 @@ Passwords have been used for authentication for a long time, even though they ha
   23    23 
   24    24 In short: Passwords are in too many places.
   25    25 
   26    -1 # Two Factor Authentication (2FA)
   -1    26 ## Two Factor Authentication (2FA)
   27    27 
   28    28 Now, replacing passwords all at once didn't seem realistic. Also, all the
   29    29 alternatives we had available came with issues of their own. So instead of
   30    30 replacing passwords, we started adding other authentication mechanisms on top.
   31    31 
   32    -1 # One-Time Passwords
   -1    32 ## One-Time Passwords
   33    33 
   34    34 A very common approach to two factor authentication is to send one-time
   35    35 passwords over a side channel such as
@@ -45,7 +45,7 @@ phishing is easy: Attackers can just call users and say "I need you to verify
   45    45 your identity by telling me the current code" and they are in. Also, the
   46    46 symmetric secrets cannot be hashed on the server.
   47    47 
   48    -1 # Something you own
   -1    48 ## Something you own
   49    49 
   50    50 Many people say that the two factors in "two factor authentication" are
   51    51 knowledge and possession. Sometimes they also add biometrics ("something you
@@ -70,7 +70,7 @@ are not perfect. I fear we might get into trouble if our crypto protocols start
   70    70 to depend on TPMs. Instead, we should think of them as obstacles. They make
   71    71 attacks harder, but don't give any guarantees.
   72    72 
   73    -1 # Multi Factor Authentication (MFA)
   -1    73 ## Multi Factor Authentication (MFA)
   74    74 
   75    75 My impression is that the term "2FA" is slowly being displaced by "MFA". The
   76    76 "multi" is not so much about "two or more factors", but more about a move to a
@@ -83,7 +83,7 @@ This also means that we are in a time of change, kinda post-password. We
   83    83 already know that passwords are a thing of the past, but we have not yet
   84    84 settled on a new approach.
   85    85 
   86    -1 # Single Sign-On (SSO)
   -1    86 ## Single Sign-On (SSO)
   87    87 
   88    88 Let's shift gears for a moment and think about SSO.
   89    89 
@@ -100,7 +100,7 @@ website (*relying party*), but the actual authentication is done by an
  100   100     mechanisms (long random passwords, challenge-response, asymmetric
  101   101     cryptography, …).
  102   102 
  103    -1 # Local Identity Providers
   -1   103 ## Local Identity Providers
  104   104 
  105   105 If the identity provider is running on your devce, the authentication doesn't
  106   106 need to involve the network, which significantly reduces the attack surface.
@@ -114,7 +114,7 @@ Your SSH keys also act as local identity providers. Compared to password
  114   114 managers, they use a much better protocol to communicate with the relying
  115   115 party.
  116   116 
  117    -1 # WebAuthn / FIDO2
   -1   117 ## WebAuthn / FIDO2
  118   118 
  119   119 [WebAuthn](https://www.w3.org/TR/webauthn/) is a new JavaScript interface. Even
  120   120 though it is often talked about in the context of MFA, I believe it is more
@@ -152,7 +152,7 @@ cryptography to communicate between the authenticator and the relying party and
  152   152 that it has some other benefits (e.g. use of TPMs) that even put it ahead of
  153   153 SSH in terms of security.
  154   154 
  155    -1 # Client-side MFA
   -1   155 ## Client-side MFA
  156   156 
  157   157 So far we have discussed that WebAuthn is a form of local SSO. It can be used
  158   158 as a building block for MFA either by using it as one of several authenticaion
@@ -181,7 +181,7 @@ Apart from user verification, authenticators can also check user presence.
  181   181 However, relying parties have no control over that and it is always required.
  182   182 That means that authentication without user interaction is not possible.
  183   183 
  184    -1 # Moving beyond passwords
   -1   184 ## Moving beyond passwords
  185   185 
  186   186 As explained in the beginning, the goal is to get rid of passwords completely.
  187   187 The buzzword a year ago was "passwordless", the current iteration is "passkey".
@@ -212,7 +212,7 @@ the same relying party becomes a bit more complicated. Either I have different
  212   212 authenticators, or the authenticator allows me to pick one, or the relying
  213   213 party receives all keys and asks me which one to use.
  214   214 
  215    -1 # Recovery
   -1   215 ## Recovery
  216   216 
  217   217 Before ending this post, we also have to look into some potential issue. The
  218   218 first one is recovery.
@@ -236,7 +236,7 @@ the same side channel or recovery keys are stored in the same password manager
  236   236 as the password. If that is the case, you are not doing MFA and not gaining any
  237   237 security. So make sure that your recovery options are solid!
  238   238 
  239    -1 # Account enumeration attacks
   -1   239 ## Account enumeration attacks
  240   240 
  241   241 When we are thinking about password-less approaches we also have to consider
  242   242 some attacks that have been solved for passwords a long time ago.
@@ -252,7 +252,7 @@ enumeration in that case? The
  252   252 creating a fake key in that case, but that sounds like there could be all kinds
  253   253 of footguns.
  254   254 
  255    -1 # Conclusion
   -1   255 ## Conclusion
  256   256 
  257   257 After reading and hearing a lot about MFA, I had to structure all that
  258   258 information. I believe the idea to think of WebAuthn as local SSO can be

diff --git a/_content/posts/2023-10-13-logging/index.md b/_content/posts/2023-10-13-logging/index.md

@@ -5,7 +5,7 @@ than would be needed for such a simple task. But this library also offers a lot
    5     5 of flexibility for advanced users as well as shortcuts for simple use cases. So
    6     6 let's take a look.
    7     7 
    8    -1 # Creating log records
   -1     8 ## Creating log records
    9     9 
   10    10 Typically you would create log records like this:
   11    11 
@@ -35,7 +35,7 @@ instead, e.g. `logging.error()`. These will use the root logger. If handlers
   35    35 have not yet been configured (see next section), these shortcuts will also
   36    36 make sure that log records are written to stderr.
   37    37 
   38    -1 # Configuring handlers
   -1    38 ## Configuring handlers
   39    39 
   40    40 Log records are sent to stderr by default. In production settings you usually
   41    41 want something more involved, so you have to configure handlers.
@@ -128,7 +128,7 @@ can receive configuration in JSON format. I am not sure why you would want to
  128   128 do that and I find it rather strange that this is included in the standard
  129   129 library.
  130   130 
  131    -1 # Attaching handlers to specific loggers
   -1   131 ## Attaching handlers to specific loggers
  132   132 
  133   133 In most cases you will want to attach your handlers to the root logger and then
  134   134 filter records there. But you can also attach handlers to different loggers.
@@ -162,7 +162,7 @@ logging.config.dictConfig({
  162   162 This way, log records from the "audit" namespace will be logged to a file
  163   163 instead of stderr.
  164   164 
  165    -1 # Recommendations
   -1   165 ## Recommendations
  166   166 
  167   167 `logging` has lots of flexibility, so much so that it is sometimes hard to know
  168   168 how to do simple things. So here are some recommendations:
@@ -178,7 +178,7 @@ how to do simple things. So here are some recommendations:
  178   178     of `WARNING`. To avoid confusion, I strongly recommend to reset that to
  179   179     `NOTSET`.
  180   180 
  181    -1 # Wishful thinking
   -1   181 ## Wishful thinking
  182   182 
  183   183 With that said, there are some things in `logging` that I wish were different:
  184   184 
@@ -198,7 +198,7 @@ With that said, there are some things in `logging` that I wish were different:
  198   198     It adds a lot of complexity without a tangible benefit because you could
  199   199     achieve the same thing with filters.
  200   200 
  201    -1 # Conclusion
   -1   201 ## Conclusion
  202   202 
  203   203 The right logging configuration is crucial. If your logs get lost you cannot
  204   204 debug issues. And if you do not get notified about errors, you might not even

diff --git a/_content/posts/2023-10-29-jmap-calendars/index.md b/_content/posts/2023-10-29-jmap-calendars/index.md

@@ -1,4 +1,4 @@
    1    -1 # The old thing: CalDAV
   -1     1 ## The old thing: CalDAV
    2     2 
    3     3 The predominant protocol used for syncing calendars is CalDAV
    4     4 ([RFC 4791](https://www.rfc-editor.org/rfc/rfc4791)). CalDAV is a weird
@@ -95,7 +95,7 @@ Frustrated with all those issues, I started thinking about a new protocol that
   95    95 could replace CalDAV. After a bit of research, I found that someone had already
   96    96 done that work.
   97    97 
   98    -1 # The new thing: JMAP Calendars
   -1    98 ## The new thing: JMAP Calendars
   99    99 
  100   100 [JMAP Calendars](https://jmap.io/spec-calendars.html) is a draft spec to send
  101   101 events in JSCalendar format