<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sivasubramanyam A</title>
    <description>The latest articles on Forem by Sivasubramanyam A (@astronomersiva).</description>
    <link>https://forem.com/astronomersiva</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F240298%2Fd2bdccdd-173e-478d-86d1-ebbf9f921e81.png</url>
      <title>Forem: Sivasubramanyam A</title>
      <link>https://forem.com/astronomersiva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/astronomersiva"/>
    <language>en</language>
    <item>
      <title>Using different Git commit authors for personal and work projects</title>
      <dc:creator>Sivasubramanyam A</dc:creator>
      <pubDate>Mon, 07 Oct 2019 19:14:25 +0000</pubDate>
      <link>https://forem.com/astronomersiva/using-different-git-commit-authors-for-personal-and-work-projects-36he</link>
      <guid>https://forem.com/astronomersiva/using-different-git-commit-authors-for-personal-and-work-projects-36he</guid>
      <description>&lt;p&gt;If you are somebody like me who has both personal and work projects in your development setup, you will probably be setting up the commit author each time you clone a repo.&lt;/p&gt;

&lt;p&gt;While it's foolproof, it can feel annoying to do this often. I was looking for a solution to this and here's what I found.&lt;/p&gt;

&lt;p&gt;It is possible to include &lt;code&gt;.gitconfig&lt;/code&gt; files in other &lt;code&gt;.gitconfig&lt;/code&gt; files. An interesting feature in Git is that you can do this conditionally.&lt;/p&gt;

&lt;p&gt;Let's use this feature to our advantage now. In your &lt;code&gt;~/.gitconfig&lt;/code&gt;, do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ~/.gitconfig&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;user]
    email &lt;span class="o"&gt;=&lt;/span&gt; personal@email.com
    name  &lt;span class="o"&gt;=&lt;/span&gt; Siva

&lt;span class="o"&gt;[&lt;/span&gt;includeIf &lt;span class="s2"&gt;"gitdir:~/work/"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    path &lt;span class="o"&gt;=&lt;/span&gt; .gitconfig-work

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What this does is that, it sets the commit author's name to &lt;code&gt;Siva&lt;/code&gt; and email to &lt;code&gt;personal@email.com&lt;/code&gt;. When a repository's path starts with &lt;code&gt;~/work&lt;/code&gt;, it includes the configuration in &lt;code&gt;.gitconfig-work&lt;/code&gt;. Now, if &lt;code&gt;.gitconfig-work&lt;/code&gt; has the following contents, the commits in that repo alone will use the following user(essentially overriding the previous user).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ~/.gitconfig-work&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;user]
    email &lt;span class="o"&gt;=&lt;/span&gt; official@company.com
    name  &lt;span class="o"&gt;=&lt;/span&gt; Mr. Siva
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using the above setup, all Git repositories, except the ones under the path &lt;code&gt;~/work/&lt;/code&gt; use my personal details and the ones under &lt;code&gt;~/work&lt;/code&gt; are committed with my official details.&lt;/p&gt;

</description>
      <category>workflow</category>
      <category>git</category>
    </item>
    <item>
      <title>How are identicons generated?</title>
      <dc:creator>Sivasubramanyam A</dc:creator>
      <pubDate>Sun, 06 Oct 2019 13:06:52 +0000</pubDate>
      <link>https://forem.com/astronomersiva/how-are-identicons-generated-2ip2</link>
      <guid>https://forem.com/astronomersiva/how-are-identicons-generated-2ip2</guid>
      <description>&lt;p&gt;We have seen them everywhere. From GitHub to Stack Overflow, identicons have been the face of users who do not have an associated Gravatar or a profile photo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyh9xk09854jvm4xsp9b8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyh9xk09854jvm4xsp9b8.png" alt="Identicon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to figure out how these were generated and came across &lt;a href="https://github.blog/2013-08-14-identicons/" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt; by GitHub where they announced the introduction of identicons on their site.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our Identicons are simple 5×5 “pixel” sprites that are generated using a hash of the user’s ID. The algorithm walks through the hash and turns pixels on or off depending on even or odd values. These generated patterns, combined with hash-determined color values, ensures a huge number of unique Identicons.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While the identicon itself is a 5x5 image, one can notice that it is symmetrical. The fourth and fifth columns mirror the second and first columns respectively. This implies that it's sufficient to express these in a 3x5 matrix. So, a 15 digit(&lt;code&gt;3 x 5 = 15&lt;/code&gt;) sequence is sufficient to represent an identicon. As for the color, we can use a 6 bit sequence from this 15 bit number itself and generate a color code in the hex format.&lt;/p&gt;

&lt;p&gt;Let's try and build this now.&lt;/p&gt;

&lt;p&gt;The 15 digit sequence has to be based on the given string and should be reproducible. Let's use hashing to solve this. We can use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#Converting_a_digest_to_a_hex_string" rel="noopener noreferrer"&gt;this example&lt;/a&gt; from MDN to generate the hash. The SHA-1 algorithm shouldn't be used for anything serious but since this is a fun little project, let's go with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hexString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;byteArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hexCodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;byteArray&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hexCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;paddedHexCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hexCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;paddedHexCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hexCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SHA-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleInput&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;userInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hexString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// logs f10e2821bbbea527ea02200352313bc059445190&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to convert this 40 character long hash into a 15 bit sequence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flqz1b9iidmaazrmjebc7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flqz1b9iidmaazrmjebc7.png" alt="Grid Placement"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above matrix, the value of &lt;code&gt;n&lt;/code&gt; at position &lt;code&gt;(i, j)&lt;/code&gt; is given by &lt;code&gt;i*3 + j&lt;/code&gt;. We can then simply look at the &lt;code&gt;n&lt;/code&gt;th position of the hash for &lt;code&gt;0 &amp;lt;= n &amp;lt;= 14&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This can be represented in code as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To determine the mirrored values to fill the fourth and fifth columns, we can modify the above code to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;J&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;J&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the above code, we have arrived at the hash &lt;code&gt;f10e2821bbbea52&lt;/code&gt;. We now need to find a way to use this hash to determine which of the boxes in the grid have to be filled. One trivial solution to this is to take each of these characters and check if it is divisible by 2 in the decimal form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;J&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;J&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldFill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All that's left is to determine the color of the fill. While we can just use a sequence of 6 digits from the hash &lt;code&gt;f10e2821bbbea52&lt;/code&gt; that we generated above, let's use some of the extra characters from the 40 character long hash that we generated previously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`#&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;f10e2821bbbea527ea02200352313bc059445190&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// logs #445190&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now putting this all together using some JavaScript and HTML Canvas, we get a working generator that produces identicons similar to the ones generated by GitHub.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/siva-a/embed/JjjjJYo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>learning</category>
      <category>walkthrough</category>
    </item>
    <item>
      <title>lego, not yet another Static Site Generator</title>
      <dc:creator>Sivasubramanyam A</dc:creator>
      <pubDate>Sat, 05 Oct 2019 08:04:59 +0000</pubDate>
      <link>https://forem.com/astronomersiva/lego-not-yet-another-static-site-generator-1onn</link>
      <guid>https://forem.com/astronomersiva/lego-not-yet-another-static-site-generator-1onn</guid>
      <description>&lt;p&gt;I have been working for over a year on lego, a static site generator written in JavaScript. When I decided to rewrite my site, I had a wide variety of SSGs to choose from. I eventually narrowed down my choices to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Gatsby&lt;/strong&gt; - I really liked how optimised the output was with Gatsby. The only issue I had with Gatsby was the slow build timings.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Hugo&lt;/strong&gt; - I loved Hugo for its speed. However, the templating language was frankly too disappointing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Jekyll&lt;/strong&gt; - This was fast enough for my site's size and the templating language, Liquid, was pretty similar to Jinja2. However, doing Gatsby like optimisations was challenging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had way too much free time on my hands so I did what every bored developer does. Write my own framework. In this case, I decided to write my own static site generator that emulates the good parts of these three frameworks.&lt;/p&gt;

&lt;p&gt;I had a few requirements out of this and decided to try building it for a week or so and see how feasible this was.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Support Liquid(recently added Nunjucks support).&lt;/li&gt;
&lt;li&gt;  Support Markdown posts, data in YAML(later extended to JS and JSON).&lt;/li&gt;
&lt;li&gt;  Transpile and uglify JS with terser, use PostCSS for CSS(both use &lt;code&gt;browserslist&lt;/code&gt; to determine targets).&lt;/li&gt;
&lt;li&gt;  Revision assets like JS, CSS and images.&lt;/li&gt;
&lt;li&gt;  Optimise images.&lt;/li&gt;
&lt;li&gt;  Extract and inline critical styles with &lt;a href="https://github.com/addyosmani/critical"&gt;critical&lt;/a&gt; for all pages.&lt;/li&gt;
&lt;li&gt;  Minify HTML of all pages.&lt;/li&gt;
&lt;li&gt;  Generate a tag-wise listing of posts. For example, &lt;code&gt;site/tags/javascript&lt;/code&gt; should list all pages tagged &lt;code&gt;JavaScript&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Live Reload during development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Surprisingly it turned out pretty well. There were still a few rough edges but I quickly ported over my site in the hopes that I could fix them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is when the fun began&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;lego was taking about 5-6 seconds to start up. While this was not that bad compared to Gatsby, I wanted to squeeze out as much performance out of it as I could. The whole purpose of this project was to learn something and have fun in the process so I decided to profile lego. A few interesting things stood out.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Just requiring PostCSS plugins was taking a second or two.&lt;/li&gt;
&lt;li&gt;  Some code paths were running more often than necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After fixing these, it came down to about 2-4 seconds.&lt;/p&gt;

&lt;p&gt;This is when I started looking into caching. While coming up with a technique for this was challenging, the actual &lt;a href="https://github.com/astronomersiva/lego/blob/master/lib/utils/cache.js"&gt;implementation&lt;/a&gt; was rather trivial. After implementing caching, I felt satisfied with this whole endeavour of writing my own SSG. I now had a fast, performant SSG that generated an optimised site.&lt;/p&gt;

&lt;p&gt;Right now, lego starts up a development server for my own &lt;a href="https://siva.dev"&gt;site&lt;/a&gt; in under 600ms. Rebuilds take under a couple hundred milliseconds. Production builds take about 20 seconds!&lt;/p&gt;

&lt;p&gt;I wrote a benchmark to test all this. When Liquid templates are used, lego is about 1.5x faster than Jekyll and when Nunjuck templates are used, lego is a cool &lt;strong&gt;8.7x faster than Jekyll.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I then added a few more things like RSS Feed generation and sitemap generation based on my own needs. While lego supports auto-generating responsive images, I think it's a little less robust and I will start paying attention to it in the coming days.&lt;/p&gt;

&lt;p&gt;If you are feeling adventurous and want to try this out,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;npm i -g @astronomersiva/lego&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a site using &lt;code&gt;lego g my-awesome-site&lt;/code&gt;. This will generate a dummy site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;lego s&lt;/code&gt; to start the server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also checkout the code on &lt;a href="https://github.com/astronomersiva/lego/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have a great weekend folks!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>sideprojects</category>
    </item>
  </channel>
</rss>
