<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Lucas Becker</title>
  <subtitle></subtitle>
  <link href="https://lucasbecker.de/feeds/atom" rel="self" type="application/atom+xml" />
  <link href="https://lucasbecker.de/" rel="alternate" type="text/html" />
  <id>https://lucasbecker.de/feeds/atom</id>
  <updated>2020-06-17T12:00:00Z</updated>
  <rights></rights>
  <generator uri="https://github.com/omz13/kirby3-feeds">omz13-feeds</generator>
  <entry>
    <title>Stop Assuming In Design</title>
    <id>https://lucasbecker.de/posts/stop-assuming-in-design</id>
    <updated>2020-06-17T12:00:00Z</updated>
    <published>2020-06-17T12:00:00Z</published>
    <link href="https://lucasbecker.de/posts/stop-assuming-in-design" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section class="star">
<h3>Prologue</h3>
<p>I <em>love</em> dark themes. I think they are a bless for the eyes.</p>
<p>With monochrome displays (those chunky <a href="https://en.wikipedia.org/wiki/Light-on-dark_color_scheme">CRTs</a>) we once already had bright on dark. As technology evolved we gained the possibility of enjoying full color monitors, where we seemingly could simulate the more relatable paper office featuring black ink on white paper. For the next 30 years or so everybody was exposed to the dogma of the bright background.<br />
The comparison to paper was always deeply flawed in my opinion, since paper has no backlight. Rest assured: if paper would be illuminated we would have had dark paper.</p>
<p>Technically spoken there is no big difference in photons; it doesn&#8217;t matter if they are emitted or reflected. However reflected light matches almost by definition the brightness of the surrounding environment and also shares its white balance.<br />
Also note: normal paper is not <em>really white</em> <label for="15701" class="margin-toggle"> &#8853;</label><input type="checkbox" id="15701" class="margin-toggle"/><span class="marginnote" role="aside">Nothing in the real world is a truly Lambertian surface, and nothing is of fully white color either, which would make the object perfectly specular (all photons are reflected). A classic mistake in rendering is trying to make a clay model render happen with a fully diffuse and fully white material – those two cancel each other out, leading to long render times and a bland image.</span>– we <em>know</em> it should be white, so our brain does some pretty good job on white balancing it for us so we <em>think</em> it looks white. In RGB color terms a white paper is more along the lines of a light grey (value of ~225–230 per color channel).<br />
Long story short: Representing the <em>white paper model</em> on screen with a full RBG white of 255 is wrong, misleading, and hurts your eyes.</p>
</section>
<section>
<p>But let&#8217;s fast forward to this day and let&#8217;s have a look on what your website might look in my browser:</p>
<figure><a class="lightbox data-group: samples" href="https://lucasbecker.de/media/pages/posts/stop-assuming-in-design/437600219-1592042742/p1.png"><img alt="" src="https://lucasbecker.de/media/pages/posts/stop-assuming-in-design/437600219-1592042742/p1.png"></a><figcaption>The background is styled, but the text is not.</figcaption></figure>
<figure><a class="lightbox data-group: samples" href="https://lucasbecker.de/media/pages/posts/stop-assuming-in-design/1572160779-1592042748/p2.png"><img alt="" src="https://lucasbecker.de/media/pages/posts/stop-assuming-in-design/1572160779-1592042748/p2.png"></a><figcaption>The text is styled, but the background ain&#8217;t.</figcaption></figure>
<p>Both webpages were featured on the HN frontpage on 2020-01-13.</p>
<h2>Golden rule</h2>
<p>This leads us to the following golden rule which can improve the life of everybody:<br />
<strong>Be explicit, not implicit!</strong><label for="9f697" class="margin-toggle"> &#8853;</label><input type="checkbox" id="9f697" class="margin-toggle"/><span class="marginnote" role="aside">Or don&#8217;t style at all, so the users preferences can take over.</span><br />
Never trust that a user has the same settings as you do. Or in other words: <em>Your</em> defaults aren&#8217;t mine.</p>
<h3>Expectation and Reality in Webdesign</h3>
<p>For those of you who are doing webdesign let me rephrase it into one simple rule:<br />
If you style the background, you have to style the foreground (<em>i.e. text</em>).<br />
And vice versa. I will thank you for it.</p>
</section>
<section>
<h3>Prologue</h3>
<p>It&#8217;s easy to see that this article can be applied to much more than just some colors. In the end it is about accessibility: Don&#8217;t assume your user uses a mouse, don&#8217;t assume your user can figure out where you&#8217;ve hidden that <em>one</em> option&#8230; The possibilities are endless.</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>Forwarding the Digitalization</title>
    <id>https://lucasbecker.de/posts/forwarding-the-digitalization</id>
    <updated>2020-05-17T13:15:00Z</updated>
    <published>2020-05-17T13:15:00Z</published>
    <link href="https://lucasbecker.de/posts/forwarding-the-digitalization" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section>
<p>Have you also noticed how &#8220;digitalization&#8221; is still a foreign concept for many out there? Especially for those who deal with &#8220;official&#8221; stuff.<br />
<strong>Of course</strong> you just can not send them an email with the PDF filled in digitally!<br />
Heck, some people still even want to get a FAX!</p>
<video controls><source src="https://lucasbecker.de/media/pages/posts/forwarding-the-digitalization/3326194963-1589722646/sandwich.webm" type="video/webm"><p>Your browser doesn&#8217;t support this embedded video.</p></video>
<p>A few days back someone on <a href="https://news.ycombinator.com/item?id=23157408">HackerNews</a> posted a link to a service he built, where you can upload a PDF and you will get it back looking like if it was scanned in – a bit blurry, not well aligned, etc.<label for="4fc3e" class="margin-toggle"> &#8853;</label><input type="checkbox" id="4fc3e" class="margin-toggle"/><span class="marginnote" role="aside">There is also <a href="https://gitlab.com/edouardklein/falsisign" target="_blank">FalsiScan</a>, which carries it to extremes giving you the possibility to insert your signature in the step as well. <a href="https://news.ycombinator.com/item?id=22811653" target="_blank">[HN comments]</a></span></p>
<p>But basically it&#8217;s just these two shell commands<label for="163ae" class="margin-toggle sidenote-number"></label><input type="checkbox" id="163ae" class="margin-toggle"/><span class="sidenote">Easily doable with WSL as well.</span> who do all the work:</p>
<pre><code class="language-shell">convert -density 150 input.pdf -colorspace gray -linear-stretch 3.5%x10% -blur 0x0.5 -attenuate 0.25 +noise Gaussian -rotate 0.5 temp.pdf

gs -dSAFER -dBATCH -dNOPAUSE -dNOCACHE -sDEVICE=pdfwrite -sColorConversionStrategy=LeaveColorUnchanged -dAutoFilterColorImages=true -dAutoFilterGrayImages=true -dDownsampleMonoImages=true -dDownsampleGrayImages=true -dDownsampleColorImages=true -sOutputFile=output.pdf temp.pdf</code></pre>
<p>But it turned out not to be that easy: ImageMagick has now a security policy in place which will prohibit processing PDFs and PostScript files. Trying to invoke ImageMagick with <code>convert</code> will fail with the fairly ambigous <code>not authorized 'file.pdf' @ &lt;somewhere&gt;</code><br />
What a nice and helpful error message! It ticks all points:</p>
<ul>
<li>✅ Doesn&#8217;t tell you what&#8217;s wrong. (What do you mean, <em>&#8216;not authorized&#8217;</em>?)</li>
<li>✅ Doesn&#8217;t tell you how to resolve it.</li>
<li>✅ Gives you superfluous information you can&#8217;t use. You don&#8217;t care at all where the precise location of this error in the code is.</li>
</ul>
<p>Poking around a bit gives the answer of an aggressive security safeguard in place. Since we only edit our very own PDF files we don&#8217;t care about malicous content – we want to get work done! To read more about this topic in detail I can recommend this <a href="https://cromwell-intl.com/open-source/pdf-not-authorized.html">article</a>, which also supplies the solution:<br />
Just edit this file <code>/etc/ImageMagick-6/policy.xml</code> to make sure the <code>rights</code> are not set to &#8216;none&#8217;.</p>
<pre><code class="language-xml">&lt;policy domain="coder" rights="read|write" pattern="PDF,PS" /&gt;</code></pre>
<p>Having done that you&#8217;re good to go to and enjoy your circumvention of this bureaucratic system.</p>
<p>I already used it now in various correspondence – among others with a bank, who rejected a digitally signed PDF. Welp, then they got my faux-printed doc. You fools!</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>How do I get my offscreen palettes back?</title>
    <id>https://lucasbecker.de/posts/how-to-get-back-missing-archicad-palettes</id>
    <updated>2020-04-10T14:25:00Z</updated>
    <published>2020-04-10T14:25:00Z</published>
    <link href="https://lucasbecker.de/posts/how-to-get-back-missing-archicad-palettes" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section>
<p>If you are an Archicad user and employ a multi monitor setup, most possibly with a notebook, you might have encountered this problem already:<br />
When detached from the external monitor you are missing some of the palettes! They are still there in fact – just <em>offscreen</em>, outside of the boundary of your current monitor with no way of getting them back.</p>
<p>Some tips online seem to suggest that applying one of the default work environments (or workspace schemes) might help to mitigate this. This did not work for me however, so I went to look for another solution to get my missing Archicad palette back.</p>
<h2>Craft your own solution</h2>
<p>We still have an ace up our sleeve! Archicad lets us <a href="https://github.com/runxel/archicad-workspaces">ex- and import</a> the settings of our work environment which includes the workspace schemes.<br />
Let&#8217;s do that! Go to Options &gt; Work Environment &gt; Workspace Schemes and export your current scheme. Then open the file you just saved – it&#8217;s a &#8220;simple&#8221; XML and can be opened with any editor.</p>
<p>First we need to find the GUID<label for="07ebe" class="margin-toggle sidenote-number"></label><input type="checkbox" id="07ebe" class="margin-toggle"/><span class="sidenote"><em>Globally unique identifier</em></span> of the palette we need to get back onto our screen. For me it was the PhotoRendering Settings palette. You can find all palettes under the <code>&lt;PaletteVisibilityTable&gt;</code> node. The code looks like this:</p>
<pre><code class="language-xml">&lt;PaletteVisibility comment="PhotoRendering Settings" guid="6E7F80CC-565C-4D21-814C-7D6865DFB6F2" value="1"/&gt;</code></pre>
<p>Write that GUID down, we will need it in a minute! Also set <code>value</code> to <code>1</code>, so you can see directly if it worked, when we load the scheme back into Archicad.</p>
<p>Now scroll down until you see the <code>&lt;SizeableFloatingRootNodes&gt;</code> node. Inside you can basically copy and paste any of the existing items. There are two things that need our attention: the <code>paletteGuid</code> attribute inside of <code>&lt;DockPalette&gt;</code>, where you have to put the GUID you just copied, and the <code>Rect</code> attribute of <code>&lt;SizeableDockData&gt;</code>.</p>
<pre><code class="language-xml">&lt;SizeableDockData Rect="334, 220, 681, 876" ScaleFactor="100" Type="Floating"&gt;
    &lt;DockPalette comment="PhotoRendering Settings" paletteGuid="6E7F80CC-565C-4D21-814C-7D6865DFB6F2" ratio="0" visibility="true"&gt;
    &lt;/DockPalette&gt;
&lt;/SizeableDockData&gt;</code></pre>
<pre><code>This part is the key. Note 'Rect' and 'paletteGuid' attributes.</code></pre>
<p><code>Rect</code> has four comma separated values. They are the pixel coordinates<label for="d1b5e" class="margin-toggle sidenote-number"></label><input type="checkbox" id="d1b5e" class="margin-toggle"/><span class="sidenote">With the upper left corner of your main <em>screen</em> being <code>0,0</code>.</span> of the upper left and lower right corner of the palette<label for="b7a9a" class="margin-toggle sidenote-number"></label><input type="checkbox" id="b7a9a" class="margin-toggle"/><span class="sidenote">Without any window decorations. See also image.</span>. Positive X-values are to the right, positive Y-values are below.</p>
<figure><a class="lightbox" href="https://lucasbecker.de/media/pages/posts/how-to-get-back-missing-archicad-palettes/1814958435-1586521987/palette.png"><img alt="" src="https://lucasbecker.de/media/pages/posts/how-to-get-back-missing-archicad-palettes/1814958435-1586521987/palette.png"></a></figure>
<p>When editing the numbers just be sure the palette will now sit inside the dimensions of your monitor. If you&#8217;re done save the file and load it right back into Archicad. Apply the workspace scheme and you should see your formerly missing palette!</p>
<h3>What do we learn?</h3>
<p>To be safe also keep a separate work environment for your multi monitor setup – otherwise you&#8217;d easily be upset.</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>Design Fails (1)</title>
    <id>https://lucasbecker.de/posts/design-fails-1</id>
    <updated>2020-03-25T22:15:00Z</updated>
    <published>2020-03-25T22:15:00Z</published>
    <link href="https://lucasbecker.de/posts/design-fails-1" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section>
<p>From time to time I roam around Kickstarter and take a close look at some of the campaigns. Pretty often their descriptions read like they re-invented <code>&lt;basic item&gt;</code> and furthermore promise fantastic things. One of these is <a href="https://www.kickstarter.com/projects/orangeredlife/the-new-30-ruler-one-ruler-to-rule-them-all/description">&#8220;The New 30° Ruler&#8221;</a>, which claims to be a superior ruler in every way.</p>
<p>This is not their first Kickstarter campaign; I pledged during their last campaign and got a ruler similiar to those in this campaign. They are well made and the artisanal quality is out of question.</p>
<p>I&#8217;d rather <em>question</em> a particular <em>design decision</em> they made, and why it&#8217;s made wrongly.</p>
<figure><img alt="kickstarter screenshot" src="https://lucasbecker.de/media/pages/posts/design-fails-1/2197577606-1585172265/ruler-title.jpg"><figcaption>The ruler as presented on Kickstarter.<br />
Picture by <em>Orangeredlife</em>, all rights reserved.</figcaption></figure>
<p>Maybe you can already spot what&#8217;s looking off here.</p>
<p>As usual there is an introduction video at the top of the Kickstarter page, which highlights all the good stuff this campaign has to offer.</p>
<p>Funnily enough they even show how you would expect how to operate a ruler first:</p>
<figure><a class="lightbox data-group: ruler" href="https://lucasbecker.de/media/pages/posts/design-fails-1/3918467940-1585172266/other-rulers.jpg"><img alt="" src="https://lucasbecker.de/media/pages/posts/design-fails-1/3918467940-1585172266/other-rulers.jpg"></a><figcaption>Screenshot: A traditional ruler.</figcaption></figure>
<p>Right after you can see the shiny 30° ruler:</p>
<figure><a class="lightbox data-group: ruler" href="https://lucasbecker.de/media/pages/posts/design-fails-1/2299896014-1585172268/ruler-new.jpg"><img alt="" src="https://lucasbecker.de/media/pages/posts/design-fails-1/2299896014-1585172268/ruler-new.jpg"></a><figcaption>&#8220;Look Ma! No Hands!&#8221; – Screenshot: The &#8220;New 30° Ruler&#8221;.</figcaption></figure>
<p>Apparently the &#8220;designers&#8221; behind this Kickstarter campaign are of the opinion that a ruler has been held fundamentally wrong by all people so far.</p>
<p>A bold claim, to be sure! And one I can not really agree on.<br />
Of course you&#8217;re free to hold it the other (the &#8220;right&#8221;) way, but then the numbers aren&#8217;t any longer facing you. And if you are right handed, you will always draw lines from left to right, which complicates one of the main missions of a ruler: Drawing a line with a certain length. </p>
<p>In the short clip they seem to make the point that their method is much more precise. But how to hold this ruler? You&#8217;d always need to juggle your pen beneath your holding hand&#8230;</p>
<p>I even wrote to them to explain what problem I have with this design. They shrugged it off however. I&#8217;m a bit disappointed to see they made their mistake twice&#8230;</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>De-Aspect Your Digital Negatives</title>
    <id>https://lucasbecker.de/posts/de-aspect-your-digital-negatives</id>
    <updated>2020-03-14T03:45:00Z</updated>
    <published>2020-03-14T03:45:00Z</published>
    <link href="https://lucasbecker.de/posts/de-aspect-your-digital-negatives" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section>
<p>Lately I stumbled over such a weird behaviour which not only irritated, but highly frustrated me.</p>
<h2>The Story</h2>
<p>A friend of mine took some pictures for me to edit. We use a Google Drive folder to sync our work. Google can preview a lot of file types (more than e.g. Dropbox) – but it has a &#8220;bug&#8221;: It <em>disregards</em> the metadata of the RAW files. If we wouldn&#8217;t have used a system, that didn&#8217;t implemented the spec, I would never have found out.</p>
</section>
<section>
<h2>The Problem</h2>
<div class="himg">
<p>Let&#8217;s have a closer look at the problem I encountered.<br />
See, the image to the right is the preview I got on Google Drive.<br />
Looking good so far, doesn&#8217;t it?</p>
<figure><img alt="Google Drive preview image" src="https://lucasbecker.de/media/pages/posts/de-aspect-your-digital-negatives/3353135589-1584126197/google-drive-preview.jpg"></figure>
<p>Now, that&#8217;s the same photo, downloaded, viewed as thumb in Windows Explorer.<br />
Do you spot anything fishy?</p>
<figure><img alt="Windows Explorer thumb image" src="https://lucasbecker.de/media/pages/posts/de-aspect-your-digital-negatives/1276505186-1584126111/windows-explorer-thumb.jpg"></figure>
</div>
<p>How about now: The same photo openend in Camera Raw.<br />
Exactly. <strong>There is missing a whole part of the image.</strong></p>
<figure><img alt="Camera Raw editing pane with image" src="https://lucasbecker.de/media/pages/posts/de-aspect-your-digital-negatives/3022129763-1584126112/camera-raw.jpg"></figure>
</section>
<section>
<h2>The Search</h2>
<p>At first I believed it was a thing only occuring due to up- and downloading the RAW files via Google Drive. This &#8220;easy&#8221; solution was shortly after ruptured by the insight that my friend faced the same issue with the files coming directly of his camera.</p>
<p>My second guess was that there could be some kind of &#8220;pre-cropping&#8221; taking place – and I was right – it&#8217;s just you simply can&#8217;t see, or let alone change it in Camera Raw, Lightroom, etc.</p>
<p>This is an excellent example of being spec compliant but losing your user along the way. Even worse: no program actually gives you a hint saying that there is some weird bullshit going on. So what exactly happenend?</p>
<figure><img alt="exiftool screenshot" src="https://lucasbecker.de/media/pages/posts/de-aspect-your-digital-negatives/3798149235-1584126112/exif.jpg"><figcaption>Exiftool (here the GUI is displayed) quickly revealed the problem.</figcaption></figure>
<p>The camera <em>did</em> set a 16:9 cropping to be applied to the photographs taken. That is either a setting, which was surely not activated deliberately by the photographer,<label for="795bd" class="margin-toggle"> &#8853;</label><input type="checkbox" id="795bd" class="margin-toggle"/><span class="marginnote" role="aside">Why would you even activate it? You will have to develop the photos no matter what, so you can always crop them later</span> or some online sources suggest that it&#8217;s happening automatically if you use certain focal lengths (not really sure about <em>that</em>).<br />
All of the programs, and even <em>Windows</em>, respect the spec and will use the crop setting from the RAW&#8217;s metadata. But again: They do, without telling the user about it – which I think is certainly a dark pattern.</p>
</section>
<section>
<h2>The Solution</h2>
<p>With the famous <a href="https://exiftool.org/">exiftool</a> I was able to get the original, uncropped image back:<label for="88233" class="margin-toggle"> &#8853;</label><input type="checkbox" id="88233" class="margin-toggle"/><span class="marginnote" role="aside">exiftool must be installed and in your PATH.</span></p>
<pre><code class="language-shell">exiftool -AspectRatio="" -AspectFrame="0 0 0 0" -DefaultCropOrigin="" -DefaultCropSize="" -CroppedImageWidth="&lt;width from exiftool&gt;" -CroppedImageHeight="&lt;height from exiftool&gt;" -o output.dng input.dng</code></pre>
<p>However: this <em>only</em> works with <strong>DNG, CR2 and ORF</strong>.<br />
The pictures on the other hand were taken with a Sony Alpha 330, whose RAW flavour is called <code>ARW</code>. So you might need to convert all your RAW files to DNG first. (Just use the Camera Raw save dialog.)</p>
<p>If you&#8217;re facing the same problem as me you surely want an easy way to get rid of this nonsense for a whole bunch of photos – so what wouldn&#8217;t be more suitable than a script?</p>
<p>In other news I wrote a <a href="https://github.com/runxel/powershell/blob/master/deaspect-dng.ps1">powershell script</a>:</p>
<pre><code class="language-shell">$format = "dng"  # change to cr2 or orf if needed
$search = "*." + $format
$suffix = "-da"  # suffix for renaming of the de-aspected files

function Deaspect($Filename){
    # those are getting the true original sizes
    $CmdWidth = exiftool -ImageWidth $Filename
    $CmdHeight = exiftool -ImageHeight $Filename

    $ImgWidth = $CmdWidth -replace '\D+'
    $ImgHeight = $CmdHeight -replace '\D+'

    $NewFilename = $Filename.BaseName + $suffix + $Filename.Extension

    &amp;exiftool -AspectRatio="" -AspectFrame="0 0 0 0" `
    -DefaultCropOrigin="" -DefaultCropSize="" `
    -CroppedImageWidth="$ImgWidth" `
    -CroppedImageHeight="$ImgHeight" `
    -o $NewFilename $Filename
}

Get-ChildItem -Filter $search -Recurse | ForEach-Object { Deaspect -Filename $_ }</code></pre>
<p>If you use Lightroom you can check out this <a href="https://tim.jagenberg.info/projects/deaspect/">plugin</a>.</p>
<p>I hope I could save you some time, trouble, &amp; frustration.<br />
Happy creating! 👋🏻</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>On Amusing Errors</title>
    <id>https://lucasbecker.de/posts/amusing-errors</id>
    <updated>2020-03-01T14:40:00Z</updated>
    <published>2020-03-01T14:40:00Z</published>
    <link href="https://lucasbecker.de/posts/amusing-errors" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section>
<p>One day in 2012 I logged into my server to only get really weird responses. When I checked the dashboard I saw what might have been the cause:</p>
<figure><img alt="" src="https://lucasbecker.de/media/pages/posts/amusing-errors/2193319029-1583070522/6pb.png"><figcaption>Yes, that&#8217;s about 6 Petabyte. And yes, it&#8217;s in harsh contrast to my actual 100&#160;MB storage. (I never used it for hosting.)</figcaption></figure>
<p>It seemed I owned 0,2‰ of <em>all Internet</em><label for="de284" class="margin-toggle sidenote-number"></label><input type="checkbox" id="de284" class="margin-toggle"/><span class="sidenote"><a href="https://www.live-counter.com/how-big-is-the-internet/">How big is the internet?</a></span> at this point in time.<br />
This seems to be not that much, but be aware that <em>all of Wikipedia</em> is just about 10&#160;GB in total, and <em>all of Wikimedia</em> is just about 23&#160;TB<label for="5329a" class="margin-toggle sidenote-number"></label><input type="checkbox" id="5329a" class="margin-toggle"/><span class="sidenote"><a href="https://en.wikipedia.org/wiki/Wikipedia:Size_of_Wikipedia">Size of Wikpedia</a></span>. I honestly thought it to be bigger.</p>
<p>Sadly my hoster didn&#8217;t had any humour. When I wrote to their support team I got a somewhat snotty answer. (It was still resolved the day later.)</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>Detecting User&#8217;s Language via GDL</title>
    <id>https://lucasbecker.de/posts/detecting-user-s-language-via-gdl</id>
    <updated>2020-01-30T19:10:00Z</updated>
    <published>2020-01-30T19:10:00Z</published>
    <link href="https://lucasbecker.de/posts/detecting-user-s-language-via-gdl" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section>
<p>A reoccurring question in Archicad&#8217;s GDL<label for="359d6" class="margin-toggle"> &#8853;</label><input type="checkbox" id="359d6" class="margin-toggle"/><span class="marginnote" role="aside">Geometric Description Language, a proprietary BASIC-dialect made by Graphisoft</span> is how to tackle localization. While Graphisoft localizes and translates their objects before shipping Archicad (sometimes done not by GS itself but by local resellers), independent manufacturers and programmers rather keep their objects together than splitting and duplicating the code for every language they support.</p>
<p>A user on <a href="https://archicad-talk.graphisoft.com/viewtopic.php?f=6&amp;t=68666&amp;p=306187#p306187">Architalk</a> wanted to know if there is the possibility to get to know which language Archicad is running on.<br />
While there is <code>REQ("GDL_Version")</code>, which tells us the version number of Archicad<label for="9e610" class="margin-toggle sidenote-number"></label><input type="checkbox" id="9e610" class="margin-toggle"/><span class="sidenote">At least indirectly, since <code>GDL_Version</code> and the Archicad version number relate to each other, but are different: E.g. for Archicad 23 build 3003 the output of the request would be <code>2.300000</code>.</span>, there is no dedicated command or request to get to know the language the user is using.</p>
</section>
<section>
<h2>A Clever Idea</h2>
<p>My solution is based on the fact that most users will have their <em>default Archicad library loaded</em> – and remember: those libraries are localized!</p>
<p>At the root of the provided library is a XML file called <strong>ARCHICAD Library.version</strong><br />
It looks more or less like this:</p>
<pre><code class="language-xml">&lt;productversion&gt;
  &lt;buildnumber&gt;2800&lt;/buildnumber&gt;
  &lt;projectbuildnumber&gt;4010&lt;/projectbuildnumber&gt;
  &lt;codename&gt;v2019&lt;/codename&gt;
  &lt;versionstring&gt;23.0.0&lt;/versionstring&gt;
  &lt;shortversionstring&gt;23&lt;/shortversionstring&gt;
  &lt;platform&gt;MAC32&lt;/platform&gt;
  &lt;gslanguage&gt;GER&lt;/gslanguage&gt;
  &lt;gsprodtype&gt;FULL&lt;/gsprodtype&gt;
  &lt;prefspostfix&gt;v2019 GER 2800.4010&lt;/prefspostfix&gt;
  &lt;guid&gt;{6108D34D-A54F-49CE-A83C-9B805F956D74}&lt;/guid&gt;
  &lt;supersedes-lib name="BIBLIOTHEKEN 20" guid="{FF6B2803-AC38-48C2-ABD6-6D56DD453444}"/&gt;
  &lt;supersedes-lib name="BIBLIOTHEKEN 21" guid="{7A18EB31-3044-4E99-8F54-B6CB16B6CE88}"/&gt;
  &lt;supersedes-lib name="BIBLIOTHEKEN 22" guid="{C46B01B7-097F-4F18-9B3D-71413F211E37}"/&gt;
  &lt;collapse-branches/&gt;
&lt;/productversion&gt;</code></pre>
<pre><code>ARCHICAD Library.version</code></pre>
<p>What&#8217;s interesting here is the <code>gslanguage</code> part: since users normally have no access to libraries not shipped with their Archicad, we can utilize that to see what language the user expects.</p>
</section>
<section>
<h2>The Implementation</h2>
<p>GDL has the <a href="http://gdl.graphisoft.com/reference-guide/gdl-xml-extension">XML Addon</a> which will help to traverse this XML.<br />
(It took me about an hour to figure out how this is actually supposed to work&#8230; – the GDL warnings are useless as always.)</p>
<p>In the end it is rather simple. Basically just four SLOC. I will go through all of them, but if you are in a hurry you can grab the (annotated) code example at <a href="https://github.com/runxel/GDL-playground/blob/master/objects/Get-Language/1d.gdl">GitHub</a>.</p>
<p>First we need to declare all the variables we need.</p>
<pre><code class="language-gdl">_dummy = "" ! only made so it can be ignored…
pos    = ""
nodename  = ""
nodevalue = ""
nodetype  = ""</code></pre>
<pre><code>easy stuff, right?</code></pre>
<p>Then we need to open the file. In GDL that is called a &#8220;channel&#8221;. The command for that is straightforward: &#8220;<code>OPEN</code>&#8221;:</p>
<pre><code class="language-gdl">ch = OPEN ('xml', 'ARCHICAD Library.version', 'rl')</code></pre>
<pre><code>The first parameter is the add-on type, the second the file name, and the third is the operation mode; in this case we want the flags set to `l` locally loaded file which should be opened as `r` readonly.</code></pre>
<p>Now it gets a little bit confusing<label for="6e4eb" class="margin-toggle"> &#8853;</label><input type="checkbox" id="6e4eb" class="margin-toggle"/><span class="marginnote" role="aside">All this stuff is needed, because GDL as BASIC based language can&#8217;t really work well with structured markup like XML. If you would need more data than just from one node, you would work with loops. An example of that can be found <a href="http://gdl.graphisoft.com/tips-and-tricks/how-to-use-the-gdl-xml-add-on">here</a>.</span>. A XML file can be understood like a tree, which has a root and then keeps branching out. To traverse this hierarchy we need a device which guides us through the data jumble. This interface is provided by the <code>NewPositionDesc</code> command:</p>
<pre><code class="language-gdl">r = INPUT (ch, "NewPositionDesc", _dummy, pos)</code></pre>
<pre><code>`pos` will return a new position descriptor.</code></pre>
<p>The <code>INPUT</code> instruction is used when reading XML files, you have to call it on the channel you want to read<label for="b516f" class="margin-toggle sidenote-number"></label><input type="checkbox" id="b516f" class="margin-toggle"/><span class="sidenote">It is totally possible to read from multiple files at the same time.</span>. The position descriptor will yield the <em>root</em> of the XML if you call it for the first time.</p>
<p>We now have a position descriptor initialized which currently points to the root element. With this set we can finally walk through the nodes of our XML.<br />
We do so again by using the <code>INPUT</code> instruction, but this time with a slightly different command:</p>
<pre><code class="language-gdl">rr = INPUT (ch, "MoveToNode FromFirstChild g* ELEM 1", pos, nodename, nodevalue, nodetype)</code></pre>
<p>There are a lot of things going on in just one line so let me explain that briefly:<br />
The command translates to &#8220;Move to the first<label for="857f2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="857f2" class="margin-toggle"/><span class="sidenote">The &#8220;1&#8221; in the command could be omitted.</span> child node which starts with &#8216;g&#8217;&#8221;.<br />
What might be confusing is the fact that the <code>INPUT</code> instruction set not only takes input parameters but also mutates them! The <code>pos</code> position descriptor gets fed into the command as a starting point. By the end of the command the <code>pos</code> variable will be returned with a new value – the descriptor now points to the found node. <code>nodename</code> will output &#8220;gslanguage&#8221; at this very moment.</p>
<p>But alas! We are not there yet! As you may have noticed <code>nodevalue</code> is empty. We still didn&#8217;t got the actual value since we just arrived at the node, but don&#8217;t know what&#8217;s inside. There could be more subnodes in here after all!</p>
<pre><code class="language-gdl">rrr = INPUT (ch, "MoveToNode FromFirstChild * TXT", pos, nodename, nodevalue, nodetype)</code></pre>
<pre><code>Basically the same as above, but this time we explicitely want a `TXT` value.</code></pre>
<p>And there you have it!<br />
The <code>nodevalue</code> will be the three letter string, <code>GER</code> in this case. What is still not clear to me is if <code>gslanguage</code> refers to the country version or the language. E.g. Germany, Switzerland, and Austria speak German – <del>have they their own <code>gslanguage</code> codes? Please tell me in the comments down below if you have any information on that.</del><label for="6437b" class="margin-toggle"> &#8853;</label><input type="checkbox" id="6437b" class="margin-toggle"/><span class="marginnote" role="aside">It at least definitely doesn&#8217;t adhere to <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3">ISO 3166-1 alpha-3</a> – German would be <code>DEU</code>&#8230;</span></p>
<p><br></p>
<p>I hope you found something valuable along the way.<br />
Happy coding! 👋🏻💻</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>Git for Noobs</title>
    <id>https://lucasbecker.de/posts/git-for-noobs</id>
    <updated>2019-10-14T16:05:00Z</updated>
    <published>2019-10-14T16:05:00Z</published>
    <link href="https://lucasbecker.de/posts/git-for-noobs" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section class="star">
<p>Judging by looking at my <a href="https://github.com/runxel">Github account</a> and its many repositories one might say I&#8217;d be pretty skillful at using Git.<br />
However, I am – or was – a satisfied user of the official Github Desktop GUI<label for="158f2" class="margin-toggle"> &#8853;</label><input type="checkbox" id="158f2" class="margin-toggle"/><span class="marginnote" role="aside">I know some of you will turn up your noses now.</span>. While I do not feel uncomfortable using a CLI I liked how easy it was plus enjoyed having a nice graphical overview<label for="b2278" class="margin-toggle sidenote-number"></label><input type="checkbox" id="b2278" class="margin-toggle"/><span class="sidenote"><code>git status</code> is now my favorite command</span>. And yes – maybe I was a bit frightened.<br />
Having a nice GUI seemed just more fulfilling. But <em>alas!</em> the Github GUI client has one disadvantage: You can&#8217;t add multiple remotes! The only option to go on from there is to rely on the good ol&#8217; command line.</p>
<p>What I wanted to achieve was having a remote copy of this website right here on a Github repository (so I&#8217;d would have access from everywhere), but also a live copy on my server – because FTP&#8217;ing into your server and putting files into the right places <em>manually</em> is no fun at all! <label for="f2717" class="margin-toggle sidenote-number"></label><input type="checkbox" id="f2717" class="margin-toggle"/><span class="sidenote">I also could have used a <a href="https://developer.github.com/v3/repos/hooks/">webhook</a> to transfer my data to my server whenever I push to Github – I just couldn&#8217;t be bothered by it. <span style="font-family: minima; white-space: nowrap;">¯┐(´-｀)┌¯</span></span></p>
<p>Hey, this one seems easy, right?<br />
Well – it could be, if only…</p>
<p>… if only I had experience in Git. The GUI is maybe <em>too</em> user-friendly. You can easily operate it without ever having any deeper knowledge. Something many folks actually are perturbed by.<label for="cad91" class="margin-toggle"> &#8853;</label><input type="checkbox" id="cad91" class="margin-toggle"/><span class="marginnote" role="aside"><img src=https://lucasbecker.de/media/pages/posts/git-for-noobs/3425945297-1569442049/xkcd_git.png></img><a href="https://xkcd.com/1597" target="_blank">xkcd at it again</a></span></p>
<p>The roadmap seemed clear, though the details were not. First I needed to turn my server into something Git would understand, then add my server to the local git config, and … that&#8217;s it?!</p>
</section>
<section class="star">
<p>My first problem started by not understanding the difference of <code>git init</code> and <code>git init --bare</code>. <a href="https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/">Jon Saints</a> has a nice overview on this special case. For the uninitiated: On a remote place you want to do the latter<label for="6235b" class="margin-toggle sidenote-number"></label><input type="checkbox" id="6235b" class="margin-toggle"/><span class="sidenote">Normally you name the bare repo something like <code>site.git</code>. You also don&#8217;t want to put the git repo at the document root. Later we will see, why.</span>. The <code>--bare</code> option tells Git to only store the versioning, but not the actual files in a working tree.</p>
<p>What I did was to accidentally init a <em>non-bare</em> repository on my server, and then wondered why I was getting back this error: <label for="34c5f" class="margin-toggle sidenote-number"></label><input type="checkbox" id="34c5f" class="margin-toggle"/><span class="sidenote">Actually, you can push to a non-bare repository just fine, you just can&#8217;t push to the one branch that is currently checked out. That&#8217;s because Git was made to make sure it does not lose any of your files – which could easily happen when you push to a dirty working tree. As bare repositories never have any branch checked out, you can always push to any branch of a bare repository.</span></p>
<pre><code class="language-shell">$ git push live
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
[…]</code></pre>
<p>After I figured out the mistake and set up a <em>bare</em> repo I tried to <code>git push</code> (which yielded no errors). This came with the next surprise tho, when I FTP&#8217;ed onto my server and rubbed my eyes in wonder: &#8220;Where are my files?&#8221;<br />
Welp, we learned now, a bare repo <em>has no source files</em>.<br />
Okay, so we can&#8217;t push to a non-bare repo and I miss my actual files if I push to a bare one?!</p>
<h2>The correct way</h2>
<p>To use Git for deploying you need to be aware of <em>hooks</em>.</p>
<blockquote cite="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks"><p>Git has a way to fire off custom scripts when certain important actions occur. There are two groups of these hooks: client-side and server-side. Client-side hooks are triggered by operations such as committing and merging, while server-side hooks run on network operations such as receiving pushed commits.</p></blockquote>
<p>Git already has some pre-defined hooks inside its &#8216;hooks&#8217; folder<label for="2b884" class="margin-toggle sidenote-number"></label><input type="checkbox" id="2b884" class="margin-toggle"/><span class="sidenote">In this example your bare repo <code>site.git</code> has already a subfolder called &#8216;hooks&#8217;.</span>. However there is no <code>post-receive</code> example. So let&#8217;s make a file with <code>touch post-receive</code>. Open it in your favorite editor and type:</p>
<pre><code class="language-shell">#!/bin/sh
git --work-tree=/var/www/fileshereplz --git-dir=/var/myrepo/site.git checkout -f</code></pre>
<p>Save the <code>post-receive</code> file and set the proper permissions by:</p>
<pre><code class="language-shell">chmod +x post-receive</code></pre>
<p>Don&#8217;t forget to add the new remote in your local git config!</p>
<p>Now every time you push to your server the files are getting deployed automatically. <label for="eff4f" class="margin-toggle"> &#8853;</label><input type="checkbox" id="eff4f" class="margin-toggle"/><span class="marginnote" role="aside"><a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps">More options</a> like branching etc.</span></p>
</section>
<section>
<p>After my Git debacle I saw this tweet. It just sums it all up very well:</p>
<figure><a href="https://twitter.com/MalwareTechBlog/status/1176690080687091712" rel="noopener noreferrer" target="_blank"><img alt="Listen, Git is hard!" src="https://lucasbecker.de/media/pages/posts/git-for-noobs/2950880365-1569442049/malwaretech_git.png"></a><figcaption>Listen, Git is hard!</figcaption></figure>
<h2>Only one thing left</h2>
<p>I want to push to my server without the need of typing in my password every time. This task seems easy at first glance, but vast amounts of information on the internet is just plain wrong.</p>
<p>There is the <a href="https://github.com/Microsoft/Git-Credential-Manager-for-Windows">Git Credential Manager for Windows</a>, but it sadly only works with HTTPS repos, not with SSH ones (like the one I have set up).<br />
All other things I&#8217;ve found need ridiculous amounts of workarounds and third-party programs or are actually talking about the Linux Subsystem. It&#8217;s totall nuts!</p>
<p>But lo and behold! For once Microsoft is aware of the needs of its users, and has an <a href="https://docs.microsoft.com/de-de/windows-server/administration/openssh/openssh_keymanagement">article on this topic</a>.<br />
In the more recent versions of Windows 10 we can easily get a copy of OpenSSH: </p>
<ul>
<li>Open <code>Manage optional features</code> from the start menu and make sure you have <code>Open SSH Client</code> in the list. If not, add it.</li>
<li>Open <code>Services</code> from the start menu.</li>
<li>Scroll down to <code>OpenSSH Authentication Agent</code> &gt; right click &gt; properties</li>
<li>Change the startup type from <code>Disabled</code> to <code>Automatic (Delayed Start)</code></li>
<li>Open <code>cmd</code> and type <code>where ssh</code> to confirm that indeed OpenSSH is living. You should see <code>C:\Windows\System32\OpenSSH\ssh.exe</code> as the path.</li>
<li>If you use Git you maybe <a href="https://stackoverflow.com/questions/2499331/git-with-ssh-on-windows/8713121#8713121">need to specifically point it</a> to the ssh.exe.</li>
</ul>
<p>Now every time you start your PC the ssh-agent will be fired up as well.<br />
With the help of <code>ssh-keygen</code> we can generate a public/private key pair, which <em>can</em> (but doesn&#8217;t need to) be encrypted with a passphrase.</p>
<p>Your generated keys will reside in <code>~\.ssh\</code>.<label for="68df0" class="margin-toggle"> &#8853;</label><input type="checkbox" id="68df0" class="margin-toggle"/><span class="marginnote" role="aside"><code>~</code> can be used in powershell, but not in cmd. For the latter you can use <code>%USERPROFILE%</code> tho.</span><br />
First the private key needs to be loaded into the ssh-agent by using </p>
<pre><code class="language-shell">ssh-add ~\.ssh\id_rsa</code></pre>
<p>The public key then has to be put onto your server. Some providers have an online GUI for that, others don&#8217;t. The manual way would be to put the content of <code>id_rsa.pub</code> into a file called <code>authorized_keys</code> in <code>~/.ssh/</code>.</p>
<p>If you&#8217;ve done everything correctly so far you should be able to <code>git push myserver</code> without ever typing in your ssh password again in cmd. 👍<br />
PS: Color your Windows CMD <a href="https://devblogs.microsoft.com/commandline/introducing-the-windows-console-colortool/">appropriately</a>!</p>
<hr />
<p>If you want to learn Git as well, try this beginner friendly <a href="http://rogerdudler.github.io/git-guide/">guide</a>. It helped me a bit. 🙃</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
  <entry>
    <title>You should own your platform</title>
    <id>https://lucasbecker.de/posts/own-your-platform</id>
    <updated>2019-09-23T00:10:00Z</updated>
    <published>2019-09-23T00:10:00Z</published>
    <link href="https://lucasbecker.de/posts/own-your-platform" />
    <content type="html" xml:lang="en" xml:base="https://lucasbecker.de/"><![CDATA[<section class="star">
<figure><img alt="" src="https://lucasbecker.de/media/pages/posts/own-your-platform/3990062116-1569363623/screenshot.png"></figure>
<p><a href="http://www.alwaysownyourplatform.com/">You should always own your platform</a>. So I built a site where I can write and publish things on, as well link to other cool stuff. In a fit of IndieWeb I <a href="https://indieweb.org/principles">&#8220;scratched my own itch&#8221;</a>, if you will.</p>
<p><a href="https://kevq.uk/please-add-rss-support-to-your-site">Does it come with RSS?</a> Hell yeah! It has Atom &amp; RSS.</p>
<pre><code class="language-plaintext">(•_•)
&lt;) )╯ Always
/  \

\(•_•)
 ( (&gt;   Own
  / \

(•_•)
&lt;)  )&gt;   Your Platform
/  \</code></pre>
</section>
<section>
<p>Dear reader! I hope you find interest in the content provided on this page.<br />
Let our journey begin!</p>
<p>There is one valuable lesson I already learnt while building <em>my</em> platform: <a href="https://www.johndcook.com/blog/2015/12/21/power-law-projects/">The longer it has taken, the longer it will take</a>. Maybe you learn something along the way, as well.</p>
<p>Have a great stay – or just go and build your own platform!</p>
</section>]]>
    </content>
    <author>
      <name>Lucas Becker</name>
    </author>
  </entry>
</feed>
