Working with data as text (dictionary)

Context

In markdown I need to quote from local dictionaries:

{{< read dictionary word id>}}

The data/dictionary.yaml files are structured as follows:

[word]

  • id : “word”
  • definition : |
    Multi-line text with possible emphasis and items
    1. item one
    2. item two
    that must be kept.
  • id : “word2”
    definition : |
    More text.

I wrote the following shortcode to read those files accordingly:

{{/*

This is layouts/shortcodes/read_yml.html to read YAML data files.
usage:   {{< read fileName tableName id >}}
example: {{< read dictionary word id >}}

*/}}

{{ $params := .Params }}
{{ $filename := index $params 0 }}
{{ $tableName := index $params 1 }}
{{ $id := index $params 2 }}
{{ $data := index .Site.Data $filename }}

{{ if $data }}
{{ $tableData := index $data $tableName }} <!-- Access the specified table -->
{{ if $tableData }}
{{ $value := (where $tableData "id" $id) }} <!-- Access the specific article by ID -->
{{ if $value }} <!-- Check if any articles were found -->
<p>{{ index $value 0 "content" }}</p>  <!-- Display the content of the specific ID -->
{{ else }}
<p>No "{{ $tableName }}" found with ID {{ $id }}.</p>
{{ end }}
{{ else }}
<p>No data found for the specified table.</p>
{{ end }}
{{ else }}
<p>No data found for the specified file.</p>
{{ end }}

Problem

When the text is rendered in html, the multilines are automatically removed, and the markups are not expanded.

In the example, the “word” is rendered as follows:

Multi-line text with possible *emphasis* and items 1. item **one** 2. item <b>two</b> that  must be kept."

What compels Hugo to corrupt the data (remove newlines) and treat markups like plain text?

According to the book “Hugo in action” (2022), page 75, section 3.4.3,

YAML is sensitive to indentation, and newline characters define the beginning of a new YAML key-value pair. We can use the pipe character (|) to create multiline strings that honor new lines and the greater than sign ( > ) to create multiline strings insensitive to new lines.

key1: |

Declares a multiline string with newline characters

key2: >

Because we use >, YAML ignores the newlines and joins the strings into a singe file.

In my example, all declarations turn out to be equivalent, as they all remove the newlines.

please wrap up code in ``` or use the </> button instead of quoting > to improve readability

maybe due to that your yaml is broken and the term definition is not in your shortcode.
Best to copy paste instead of fresh typing :wink:

```yaml
word:
  - id: word1
    definition: Text
```

With this dictionary.yaml

word:
  - id: word1
    definition: |
      Multi-line text with possible emphasis and items
      
      1. item *one*
      2. item *two*

      that must be kept.
  - id: word2
    definition: |
      More text.

and this shortcode call {{< read "dictionary" "word" "word1" >}}

and changing your output call to (no

tags around)

{{ if $value }}
  {{ index $value 0 "definition" | .Page.RenderString}}
{{ else }}

you will get:

<p>Multi-line text with possible emphasis and items</p>
<ol>
<li>item <em>one</em></li>
<li>item <em>two</em></li>
</ol>
<p>that must be kept.</p>

p.s. you have to have blank lines in markdown to separate the text from the list

Adding this command is a good improvement.

Now bold and italics are rendered in html.

Itemization still fails. I do have white lines to separate the text from the list. In the data file, an empty line is also present. As a result, a newline appears before the first item, but the remaining items are still wrapped around.

If the “definition” is an itemized list with subitems, the alignments are all wrong.

believe me, what I posted is exaclty what I have done based on a standard hugo new theme
adding the data file and your shortcode adjusted.

So there’s something different at your side.

If you want some to check that it does not make sense to play code-snipped ping pong. you’ll have to either share your site or prepare a minimal reproducible example. incl all the config and layouts…

p.s. subitems work fine, too

Summary
word:
  - id: word1
    definition: |
      Multi-line text with possible emphasis and items

      1. item **one**
         1. hello
         2. world
      2. item **two**
         - bullet
         - lucky luke

      that must be kept.
  - id: word2
    definition: |
      More text.

I am using a theme that may intervene with the processing. I will look into it.

Thank you

Problem found.

word:
  - id: word1
    definition: |
      Multi-line text with possible emphasis and items

      1. item **one**: **add words enough to fill the line then keep adding to cause the line to wrap. The itemized list that follows will also be wrapped.**
         a. hello
         b. world
      2. item **two**
         - bullet
         - lucky luke

      that must be kept.
  - id: word2
    definition: |
      More text.

I tried the code in a markdown editor, and it behaves as expected. The same code on Hugo + Relearn (theme) wraps lines and breaks indentations.

This ist not theme related. You have false assumptions about Markdown ordered lists.

You can just drop the Markdown of your dictonary.yaml directly in a Hugo .md file and it will still not render correctly. With any theme.

1 Like

display in an editor doesn’t mean it is rendered to the HTML you expect.

@McShelby is right, common-mark does not support alphas as list markers, so that’
s just plain text for the renderer

Change your a./b. to 1./2.

I cannot rewrite “a)” into “1.”. — I am in legal compliance, with forms and references, where citations must correspond to the original text.

Since this is a limitation of markdown, I’ll work around it. I am making the indentation letters in boldface, so they stand out when lines wrap. It is acceptable for relatively short paragraphs, but the problem will show up again with more complex text.

if it’s acceptable to switch to Pandoc for the dictionary Shortcode you could

dictionary.yaml
word:
  - id: word1
    definition: |
      Multi-line text with possible emphasis and items

      1. item **one**: **add words enough to fill the line then keep adding to cause the line to wrap. The itemized list that follows will also be wrapped.**
        a. hello
        b. world
      2. item **two**
        - bullet
        - lucky luke

      that must be kept.
  - id: word2
    definition: |
      More text.
Add pandoc to Security Config
# Default + pandoc
[security]
   enableInlineShortcodes = false

   [security.exec]
      allow = [...'^postcss$', 'pandoc', '^tailwindcss$']
      osEnv = [
         '(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+|(XDG_CONFIG_)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE)$',
      ]

   [security.funcs]
      getenv = ['^HUGO_', '^CI$']

   [security.http]
      methods = ['(?i)GET|POST']
      urls    = ['.*']

Change Shortcode
  {{ if $value }}
     {{ $opts := dict "display" "block" "markup" "pandoc" }}
     {{ index $value 0 "definition" | .Page.RenderString $opts }}
  {{ else }}
which looks good to me
<p>Multi-line text with possible emphasis and items</p>
<ol type="1">
<li>item <strong>one</strong>: <strong>add words enough to fill the line
then keep adding to cause the line to wrap. The itemized list that
follows will also be wrapped.</strong>
<ol type="a">
<li>hello</li>
<li>world</li>
</ol></li>
<li>item <strong>two</strong>
<ul>
<li>bullet</li>
<li>lucky luke</li>
</ul></li>
</ol>
<p>that must be kept.</p>
1 Like

Very nice of you. Thank you!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.