CASE: tables and indenting

We all like to tweak our tables with some nice visualisation, whether it’s top borders or something else.

But lately we’ve been seeing tables in which indenting of your code of the table is ignored, as the indenting would cause the table to break.
However, it is not the indenting that breaks the table. It’s just that Markdown is very precise and those extra tweak of your table (like top borders, which we use the ^ for) just needs to be attached to the pipes of each column.

As those issues seem to happen with more complicated tables, in which for each row we also loop through something, a case that hope can convince you to put a little bit more effort in your coding in order to achieve nice indenting:

Above is just a table to show you the indenting case (so don’t mind if the numbers or accounts or years don’t make sense :slightly_smiling_face:); it’s a table in which we will show values for 3 years back for selected accounts.

The code is something like this:

{% comment %}
=======================
      OUTPUT TABLE
=======================
{% endcomment %}

{% stripnewlines %}
| Account
| {{ current_date }}
| {{ current_date_1y }}
| {{ current_date_2y }}
| {{ current_date_3y }}
{% newline %}
|----{{ width }}%----
|----{{ width }}%----:
|----{{ width }}%----:
|----{{ width }}%----:
|----{{ width }}%----:+

{% for acc in accounts %}

  {% newline %}
  | {{ acc.link }}
  
  {% comment %}calculate the needed values for each year, while looping over 4 years{% endcomment %}
  {% for y in (1..4) %}
  
    {% comment %}create variable for each year to use in period.minus_[var]y{% endcomment %}
    {% capture minus_y %}minus_{{ INT(y-1) }}y{% endcapture %}

    {% comment %}calculate the value of each year for each mapped account{% endcomment %}
    {% assign value_acc = period.[minus_y].accounts.include_zeros | range:acc.mapped_number %}
    
    | {% if value_acc != 0 %}
        {{ value_acc | currency }}
      {% else %}
        -
      {% endif %}
      
  
  
  {% endfor %}

{% endfor %}
{% endstripnewlines %}

Now, as you can see, I need to add one last row yet (the totals), while also loop over the fixed amount of years.
If we want that, we need to add this within an if forloop.last statement, and in each column (=year) add those top borders. And you probably will go for something like this:

  {% comment %}
  TOTAL VALUES
  {% endcomment %}
  {% if forloop.last %}
{% newline %}
|^   ^

{% for y in (1..4) %}
|^  xx  ^
{% endfor %}
  
  {% endif %} 

as this would break the table:

  {% comment %}
  TOTAL VALUES
  {% endcomment %}
  {% if forloop.last %}
    {% newline %}
    |^   ^
    
    {% for y in (1..4) %}
      |^     ^
    {% endfor %}
  
  {% endif %}

The indenting is totally off in the first one, and while it works in output, in coding it just seems way off as all other code is nicely indented.

How to fix?

Well, you surely need a tad bit more coding though. The reason the table broke in the first place, is because the ^ is expected just before the | of the second column.
So we need to add it there, like this:

  {% comment %}
  TOTAL VALUES
  {% endcomment %}
  {% if forloop.last %}
    {% newline %}
    |^   
    
    {% for y in (1..4) %}
      {% comment %}re-create dynamic vars{% endcomment %}
      {% include "parts/year_values" %}
      
      ^|^  **{{ [value_y] | currency }}**  {% if forloop.last %}^{% endif %}
      
    {% endfor %}
  
  {% endif %} 

So in the first column we only have our top border on the left, while the right will be done within the forloop statement.
This means the forloop executes it like this:

^|^  **{{ [value_y] | currency }}**^|^  **{{ [value_y] | currency }}**^|^  **{{ [value_y] | currency }}**^|^  **{{ [value_y] | currency }}**

So there’s one thing missing, and that is the very last ^ in the last column, so we add that with a if forloop.last statement:

{% if forloop.last %}^{% endif %} 

Granted, it demands a bit more effort to achieve the indenting, but isn’t it worth it? :star_struck:

Complete code below:

main part

{% ic %}{::infotext}
Choose the accounts you wish to check till 3 years back: {% input custom.range.accounts as:account_collection range:"6" %}
{:/infotext}{% endic %}

<br>

{% comment %}
====================
      Variables
====================
{% endcomment %}
{% include "parts/variables" %}

{% comment %}
=======================
      OUTPUT TABLE
=======================
{% endcomment %}

{% stripnewlines %}
|----{{ width }}%----
|----{{ width }}%----:
|----{{ width }}%----:
|----{{ width }}%----:
|----{{ width }}%----:+
{% newline %}
|_  **Account**
_|_ **{{ current_date }}**
_|_ **{{ current_date_1y }}**
_|_ **{{ current_date_2y }}**
_|_ **{{ current_date_3y }}** _

{% for acc in accounts %}

  {% newline %}
  | {{ acc.link }}
  
  {% comment %}calculate the needed values for each year, while looping over 4 years{% endcomment %}
  {% for y in (1..4) %}
  
    {% comment %}create variable for each year to use in period.minus_[var]y{% endcomment %}
    {% capture minus_y %}minus_{{ INT(y-1) }}y{% endcapture %}

    {% comment %}calculate the value of each year for each mapped account{% endcomment %}
    {% assign value_acc = period.[minus_y].accounts.include_zeros | range:acc.mapped_number %}
    
    {% comment %}assign each value into a dynamic var that corresponds with the year{% endcomment %}
    {% include "parts/year_values" %}
    {% assign [value_y] = [value_y]+value_acc %}
    
    | {% if value_acc != 0 %}
        {{ value_acc | currency }}
      {% else %}
        -
      {% endif %}

  {% endfor %}
  
  {% comment %}
  TOTAL VALUES
  {% endcomment %}
  {% if forloop.last %}
    {% newline %}
    |^ &nbsp; 
    
    {% for y in (1..4) %}
      {% comment %}re-create dynamic vars{% endcomment %}
      {% include "parts/year_values" %}
      
      ^|^  **{{ [value_y] | currency }}**  {% if forloop.last %}^{% endif %}
      
    {% endfor %}
  
  {% endif %}

{% endfor %}
{% endstripnewlines %}

part variables

{% comment %}needed dates{% endcomment %}
{% assign current_date = period.end_date | date:"%d/%m/%Y" %}
{% assign current_date_1y = period.minus_1y.end_date | date:"%d/%m/%Y" %}
{% assign current_date_2y = period.minus_2y.end_date | date:"%d/%m/%Y" %}
{% assign current_date_3y = period.minus_3y.end_date | date:"%d/%m/%Y" %}
{% comment %}needed for table{% endcomment %}
{% assign nbr_cols = 5 %}
{% assign width = INT(100/nbr_cols) %}
{% comment %}values selected accounts{% endcomment %}
{% assign selected_range = custom.range.accounts %}
{% assign accounts = period.accounts.include_zeros | range:selected_range %}

part year_values

{% capture value_y %}value_{{ y }}{% endcapture %}

Thank you for this! I also always assumed it was indenting that was breaking the table, but I see that the issue lies elsewehere now. Time to update my tables I guess :slight_smile:

1 Like

That’s the spirit @ronald_groot_RSF :muscle:

Let us know if you encounter issues with it :slightly_smiling_face: