Snippet with picture and source tags get non validating closing tags

I’m using separate subpages to generate image galleries. The galleries are then used on the parent page in a textarea using a KirgyTag, something like:

(gallery: galleryname)

Using Kirby 3.6, I’m using the picture tag to use webp images like so in the gallery snippet:

 <figure>
      <picture>
        <source srcset="<?= $thumb_webp->url() ?>" type="image/webp"> 
        <source srcset="<?= $thumb->url() ?>" type="image/jpeg"> 
        <img src="<?= $thumb->url() ?>" width="<?= $thumb->width() ?>" height="<?= $thumb->height() ?>" alt="<?= $image->alt() ?>" loading="lazy">
      </picture>
      <?php if ($image->caption()->isNotEmpty()): ?>
        <figcaption><?= kti($image->caption()) ?></figcaption>
      <?php endif ?>
    </figure>

This will generate:

<figure>
  <picture>
    <source srcset="http://domain.name/path/image.webp" type="image/webp">
    <source srcset="http://domain.name/path/image.jpg" type="image/jpeg">
    <img src="http://domain.name/path/image.jpg" width="600" height="600" alt="image alt text" loading="lazy">
    </source> <!-- closing tag -->
    </source> <!-- closing tag -->
  </picture>
  <figcaption>Some caption</figcaption>
</figure>

Because this code, obviously, works as expected elsewhere I assume Parsedown adds these closing tags when using the KirbyTag? Anyway, we end up with non validating html:
Error: Stray end tag source.

Maybe try:

<source srcset="<?= $thumb_webp->url() ?>" type="image/webp" />

with a slash on the end, which i dont think is strictly neccessary but might fool parsedown into understanding this isnt a container tag.

Yes tried that, no joy

Could you share the complete tag code?

Sure:

<?php

Kirby::plugin('name/gallery', [
  'tags' => [
    'gallery' => [
      'attr' => [
        'columns'
      ],
      'html' => function($tag) {
        $galleryName = $tag->value;
        $columns = $tag->attr('columns');

        return snippet('gallery', [
          'gallery' => $galleryName,
          'columns' => $columns
        ], true);
      }
    ]
  ]
]);

Thanks, in this case the snippet is not complete…

Complete snippet:

<?php 
  $galleryPage = $page->children()->unlisted()->filterBy('title', $gallery)->first();
  if ($galleryPage):
?>
<div class="gallery">
  <?= '<h' . $galleryPage->title_level() . '>' . $galleryPage->title() . '</h' . $galleryPage->title_level() . '>' ?>
  <?= $galleryPage->text()->kt() ?>
  <ul class="unstyled<?= $columns != "" ? ' gallery-cols-' . $columns : '' ?>">
  <?php 
    $images = $galleryPage->images();
    foreach ($images->sortBy('sort', 'asc') as $image):
    $thumb = $image->thumb(['width'=> 600, 'height' => 600, 'quality' => 70]);
    $thumb_webp = $image->thumb(['width'=> 600, 'height' => 600, 'format' => 'webp', 'quality' => 70]);
  ?>
  <li>
    <figure>
      <picture>
        <source srcset="<?= $thumb_webp->url() ?>" type="image/webp" /> 
        <source srcset="<?= $thumb->url() ?>" type="image/jpeg" /> 
        <img src="<?= $thumb->url() ?>" width="<?= $thumb->width() ?>" height="<?= $thumb->height() ?>" alt="<?= $image->alt() ?>" loading="lazy">
      </picture>
      <?php if ($image->caption()->isNotEmpty()): ?>
        <figcaption><?= kti($image->caption()) ?></figcaption>
      <?php endif ?>
    </figure>
  </li>
  <?php endforeach ?>
  </ul>
</div>
<?php endif ?>

Hm, I can’t really reproduce your issue, in my test in Firefox it renders fine. I first thought that it might have to so with you calling kt()/kti() within the snippet. Maybe test if removing those method fixes the issues.

No, it didn’t. Mind you I’m looking at the page source so I’m not inspecting the element. I’m pasting the page source in the html-validater just before going live as a last check.
Inspecting the element doesn’t show the closing tags, I guess it gives a ‘corrected’ view?
So, this might be a non issue?

Yes, I looked at the page source as well because the inspector corrects such things.

reminds me of something, brb …

Ok, found the culprit:

  'markdown' => [
    'extra' => true
  ],

Setting this to false solves the problem. But, shouldn’t this work with markdown extra also?