gargoyle image Collected works and current thoughts

DRY In Blogging

More usability, reducing duplication
Making something more useful for subsequent uses could have lead to duplication, but I'm working on reducing that.

Background

I often write tutorials to cover what I learned because while I’ll probably forget the details, if I’ve written it, I’ll remember that I’ve written something on the subject, and I’ll google for it.

Realization

On a recent coaching gig I was reminded that it’s common for people working in Java to not know how to create a project from scratch. I think this is an important skill because being stopped or slowed down from trying to practice something like a kata could be just enough to stop someone from giving it a try.

I wrote yet another example of how to do that using an approach that is somewhat close to the environment the group works in.

As I wrote this, I thought I’d like to be able to just grab the commands and run them. Here’s my thinking:

  1. I remember I’ve written something
  2. I can find it using google
  3. What I find is written with details I don’t need.
  4. So it’s a bit more work to use it later

I want a summary of the steps both for myself and for someone who basically gets it but might not remember the details.

If you have a look a that example I think you’ll see that I’ve got a good first cut. I can copy the summary at the top, or I can go further into the details.

I don’t like duplication. So I wondered how could I avoid duplication, or at least reduce it, as I update the details of that example.

Here were my givens:

  1. I’m using Jekyll for github pages
  2. I don’t want to have to have the same material twice if I can avoid it
  3. It would be nice to have something I could use in other places
  4. I prefer using pure CSS

What follows is a collection of some of the things I did to get close.

Extract File

First, I realized that I wanted similar or the same content with two different views: a summary, and details. So I extracted that into its own file, which I happened to call using.gradle.steps.md.

Next, I included that file twice, wrapping it with a div with a style:


<div class="show_bash">
{% capture summary %}
    {% include_relative {{ using.gradle.steps.md }} %}
{% endcapture %}
{{ summary | markdownify }}
</div>

Now this was itself duplicated, notice the only difference is the class in thediv.


<div class="show_terminal">
{% capture summary %}
    {% include_relative {{ using.gradle.steps.md }} %}
{% endcapture %}
{{ summary | markdownify }}
</div>

Pure CSS It Up

While I could have used jquery or raw Javascript, I wanted to stick to pure CSS for the formatting.

So I created CSS (less to get the effect I wanted (this is the relevant styling):

div {
    &.show_terminal {
        div.language-bash {
            display: none;
        }
    }

    &.show_bash {
        p, ul, h1, h3, div.language-terminal  {
            display: none;
        }
    }
}

Later, I switched from using a<div> to<section> as I wanted to represent the semantic breakdown of the page.

More Duplication

While I was happy to have reduced much of the duplication, I wasn’t happy with the amount of fluff I needed to get the thing I included.

Noticing that there was a lot of duplication in thediv (later section) definition, I extracted the common stuff and passed in a parameter:

File Extracted: included_md_file


{% capture summary %}
  {% include_relative {{ include.filename }} %}
{% endcapture %}
{{ summary | markdownify }}

Using it


<section class="show_bash">
## Summary of Steps
{% include include_md_file filename="using.gradle.steps.md" %}

Notice, this does not introduce thesection or the CSS class. After some thinking, I wanted that include to stick to one thing. I also didn’t want the inclusion of content to be coupled to its semantic context, therefore

Lie Reveled

While I’m happy with the results, my desire to remove duplication between the summary and details section is not yet perfect. Instead of having the content typed twice, in differnt locations, I do still have it twice but in the same file, and close together.

Here’s an example:


~~~ bash
gradle init --type java-application
~~~

~~~ terminal
vagrant@vagrant-ubuntu16:~/src/smoke$ gradle init --type java-application

BUILD SUCCESSFUL in 0s
2 actionable tasks: 1 executed, 1 up-to-date
~~~

The command that I display in the summary of a page is formatted using the bash style. The command with a prompt and its output is formatted with the terminal style. So I still have the duplication, I think this is better than what I would have otherwise done.

As I’m still new to using Jeykll, I’m getting the hang of using it. If I could format the following line:

vagrant@vagrant-ubuntu16:~/src/smoke$ gradle init --type java-application

Something like this:

<span class="terminal">vagrant@vagrant-ubuntu16:~/src/smoke$</span><span class="bash"?gradle init --type java-application</span>

I would do it. But I have not yet figured out that magic. If I did all of the formatting by hand I probably could do that. However, I’m using the code formatting built into Jekyll.

Assuming I figure out how to get both, I won’t duplicate that. Instead, I’ll have some macro like:


{% include command_line 
  prompt="vagrant@vagrant-ubuntu16:~/src/smoke$"
  command="gradle init --type java-application" %}

But until then, I’m happy with what I’ve managed so far.

The Rest of the Story

I could some of the previous steps, but as this is as much a series of notes to myself as a description of how I got to where I got, I’m going to keep it.

I’m using Rogue with Jekyll. The following example will show why some of my efforts were unnecessary.

Example Markup

Notice that gone are the two copies of the command line. There’s just one version. I keep the one marked terminal, however bash would have worked as well.


~~~ terminal
vagrant@vagran-ubuntu16:~/src$javac -version
javac 1.8.0_181
~~~

Resulting HTML

Rogue parsing is smart enough to identify prompts versus commands and uses a span to break up the one line. This is what I wanted to do and here it is already done.


<span class="gp">vagrant@vagran-ubuntu16:~/src$</span>javac <span class="nt">-version</span>
<span class="go">javac 1.8.0_181</span>

How Each Are Rendered

After I looked at the rendered html in detail, I updated my CSS to take advantage of this.

As Summary

vagrant@vagran-ubuntu16:~/src$javac -version
javac 1.8.0_181

As Details

vagrant@vagran-ubuntu16:~/src$javac -version
javac 1.8.0_181

Now that I had what I wanted:

I then made a number of changes.

Increase Semantic Level

First, the class names were about implementation rather than intent. I updated both sections:


<section class="summary">
## Summary of Steps
{% include include_md_file filename="using.gradle.steps.md" %}


<section class="details">
## Step by Step Instructions with Example Output
{% include include_md_file filename="using.gradle.steps.md" %}

Update the CSS Accordingly

div.content {
  section {
    &.summary {
      p, h3 {
        display: none;
      }
      aside {
        p, h3 {
          display: block;
        }
      }
      code {
        span {
          &.gp, &.go {
            display: none;
          }
        }
      }
    }
  }
}

In fact, the details class has no special requirements regarding hiding anything, but I still have it identified.

Summary

I wanted to have a summary of detailed steps using pure CSS, Jekyll, and avoding duplication.

Using the tools I had and a little bit of refactoring of the structure of the files, I was able to do it and in retrospect, it was intuitive… once I understood it.

Published 08 September 2018

" Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.