Whitespace control in shortcode call?

In Shortcode templates, you can control whitespace: Introduction to Hugo Templating | Hugo

However, I can’t find something like this for the shortcode call in Markdown content.

In Jekyll, I do the following:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |
{%- comment %} Experimental feature
| Feat B  | Desc B  |
{%- endcomment %}
| Feat C  | Desc C  |

The Markdown table has a row that is currently commented out. Using - for whitespace control in the comment start and end tags carefully removes two line breaks so that the Markdown table renders as intended:

Col A Col B
Feat A Desc A
Feat C Desc C

Replicating this in Hugo doesn’t seem to be possible. This is my shortcode template for comments:

{{- if .Inner }}{{ end -}}

.Inner or InnerDedent needs to be evaluated by a shortcode with an end tag, but all this does is to swallow the content between the start and end tags of the shortcode.

It doesn’t really matter whether I use whitespace control in the shortcode template or not. It only affects the whitespace within the template, but there isn’t actually any. The line breaks around the shortcode call are not removed, breaking my table.

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |
{{% comment %}} Experimental feature
| Feat B  | Desc B  |
{{% /comment %}}
| Feat C  | Desc C  |

Everything after the closing tag is not processed as part of the table because of the extra line breaks:

Col A Col B
Feat A Desc A

| Feat C | Desc C |

My best idea is to place the shortcode tags on the beginning and end of the adjacent lines to get rid of the extra line breaks, but it’s not that great of a workaround.

So, we’re not adding or removing any whitespace.

But … is this a common issue? This is the first time I have seen someone shouting about this being a problem.

Yes, Hugo does not add additional line breaks, but I wish it would allow me to remove the line breaks similar to how you can control whitespace in shortcode templates:

{{%- comment %}}
...
{{%- /comment %}}

The line breaks make sense from an authoring perspective. It’s easier to spot the commented out content. Having to place the start and end tags on adjacent lines makes it harder to read the source file, and it feels like being forced by the tool at the expense of the content (but please don’t take this as criticism, I’m not blaming anyone - I’m merely asking for alternative workarounds or ideally a feature extension for parity with other tools like Jekyll if it’s useful for others, too).

I’m not sure if it’s a problem that people encounter commonly, but it is a common problem in the sense that line breaks are significant in Markdown. A comment shortcode might be a niche use case, but there could be other shortcodes where you would also want to control whitespace. In particular, extra line breaks are a problem in tables but to lesser extent also in lists, because it can turn an entire dense list into a spaced-out list:

Dense:

- foo
- bar
- baz
  • foo
  • bar

Spaced-out:

- foo
- bar

- baz
  • foo

  • bar

  • baz

I didn’t read the rest of this, but if you want to use a shortcode to comment out a table row, call the shortcode with the {{< >}} notation.

type|name
:--|:--
cat|felix
{{< foo >}} whatever
dog|spot
{{< /foo >}}
tweety|bird

foo.html

{{ $noop := .Inner }}
1 Like

Interesting, using {{< >}} does make a difference but I get strange results…

The table content after the comment is rendered as part of the table, which is great. However, depending on where I place the shortcode tags, there is either an empty row in the table (where the commented out content is), or the row after the comment goes missing. That doesn’t seem right?

I created a test site to easier try out the different placements and the two shortcode flavors and here are the results:

  1. Broken rendering, second half of table not processed
  2. Good
  3. Good
  4. Missing row

  1. Blank row
  2. Good
  3. Feat C cell shifted from Col A to Col B and content from the actual Col B cell is missing
  4. Missing row
### Using Markdown shortcode

Shortcode start and end tags on separate lines:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |
{{% comment %}} Experimental feature
| Feat B  | Desc B  |
{{% /comment %}}
| Feat C  | Desc C  |

Shortcode start tag on adjacent line, end tag on separate line:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |{{% comment %}} Experimental feature
| Feat B  | Desc B  |
{{% /comment %}}
| Feat C  | Desc C  |

Shortcode start tag on separate line, end tag on adjacent line:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |
{{% comment %}} Experimental feature
| Feat B  | Desc B  |
{{% /comment %}}| Feat C  | Desc C  |

Shortcode start and end tags on adjacent lines:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |{{% comment %}} Experimental feature
| Feat B  | Desc B  |
{{% /comment %}}| Feat C  | Desc C  |

### Using HTML shortcode

Shortcode start and end tags on separate lines:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |
{{< comment >}} Experimental feature
| Feat B  | Desc B  |
{{< /comment >}}
| Feat C  | Desc C  |

Shortcode start tag on adjacent line, end tag on separate line:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |{{< comment >}} Experimental feature
| Feat B  | Desc B  |
{{< /comment >}}
| Feat C  | Desc C  |

Shortcode start tag on separate line, end tag on adjacent line:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |
{{< comment >}} Experimental feature
| Feat B  | Desc B  |
{{< /comment >}}| Feat C  | Desc C  |

Shortcode start and end tags on adjacent lines:

|  Col A  |  Col B  |
|---------|---------|
| Feat A  | Desc A  |{{< comment >}} Experimental feature
| Feat B  | Desc B  |
{{< /comment >}}| Feat C  | Desc C  |

Using {{< >}} with the tags on separate lines seems to work fine in lists:

In dense list using Markdown shortcode:

- Feat A
- Feat B
{{% comment %}}
- Feat C
{{% /comment %}}
- Feat D

In dense list using HTML shortcode:

- Feat A
- Feat B
{{< comment >}}
- Feat C
{{< /comment >}}
- Feat D

If a row of empty cells is not acceptable, then I think you’re stuck with appending the opening tag to the previous line, and prepending the closing tag to the next line.

Unless your CSS is doing odd/even row stuff, this should resolve most styling problems:

td:empty {
  display: none;
}

Just make sure your shortcode chomps at both ends:

{{- $noop := .Inner -}}

If a row of empty cells is acceptable, you could skip the shortcode and take advantage of the default behavior described in the GFM spec:

type|name
:--|:--
cat|felix
||| dog|spot    <-- rendered as row of empty cells
tweety|bird

Number of leading pipes = column count + 1

1 Like

Yes, an empty row or visually hiding something with CSS are not acceptable, so I will append the opening tag to the end of the previous line. As shown in my test, prepending the closing tag to the next line loses unrelated data. It has to be on its own line.