From 3ef388f4f6cd4684dcbb7b9b42eea4171c836c5f Mon Sep 17 00:00:00 2001
From: stereobooster <stereobooster@gmail.com>
Date: Tue, 31 Oct 2023 17:53:15 +0100
Subject: [PATCH 1/5] Example of integration of picture partial

---
 config/_default/params.toml                |  1 +
 exampleSite/config/_default/params.toml    |  1 +
 layouts/_default/_markup/render-image.html | 78 +++++---------------
 layouts/partials/picture.html              | 85 ++++++++++++++++++++++
 layouts/partials/pictureDefaults.html      |  7 ++
 layouts/shortcodes/figure.html             | 52 ++++---------
 6 files changed, 126 insertions(+), 98 deletions(-)
 create mode 100644 layouts/partials/picture.html
 create mode 100644 layouts/partials/pictureDefaults.html

diff --git a/config/_default/params.toml b/config/_default/params.toml
index db391cb7..21e4748f 100644
--- a/config/_default/params.toml
+++ b/config/_default/params.toml
@@ -12,6 +12,7 @@ autoSwitchAppearance = true
 enableSearch = false
 enableCodeCopy = false
 enableImageLazyLoading = true
+enableImageWebp = true
 
 # robots = ""
 fingerprintAlgorithm = "sha256"
diff --git a/exampleSite/config/_default/params.toml b/exampleSite/config/_default/params.toml
index d828f120..41c7a5b0 100644
--- a/exampleSite/config/_default/params.toml
+++ b/exampleSite/config/_default/params.toml
@@ -12,6 +12,7 @@ autoSwitchAppearance = true
 enableSearch = true
 enableCodeCopy = true
 enableImageLazyLoading = true
+enableImageWebp = true
 
 # robots = ""
 fingerprintAlgorithm = "sha256"
diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html
index ac82a6aa..2e7a5b53 100644
--- a/layouts/_default/_markup/render-image.html
+++ b/layouts/_default/_markup/render-image.html
@@ -1,64 +1,20 @@
 {{ $url := urls.Parse .Destination }}
 {{ $altText := .Text }}
 {{ $caption := .Title }}
-{{ $lazyLoad := $.Page.Site.Params.enableImageLazyLoading | default true }}
-{{ if findRE "^https?" $url.Scheme }}
-  <figure>
-    <img
-      class="mx-auto my-0 rounded-md"
-      src="{{ $url.String }}"
-      alt="{{ $altText }}" 
-      {{ if $lazyLoad }}
-        loading="lazy"
-      {{ end }}
-    />
-    {{ with $caption }}<figcaption class="text-center">{{ . | markdownify }}</figcaption>{{ end }}
-  </figure>
-{{ else }}
-  {{ $resource := "" }}
-  {{ if $.Page.Resources.GetMatch ($url.String) }}
-    {{ $resource = $.Page.Resources.GetMatch ($url.String) }}
-  {{ else if resources.GetMatch ($url.String) }}
-    {{ $resource = resources.Get ($url.String) }}
-  {{ end }}
-  {{ with $resource }}
-    <figure>
-      <img
-        class="mx-auto my-0 rounded-md"
-        {{ if eq .MediaType.SubType "svg" }}
-          src="{{ .RelPermalink }}"
-        {{ else }}
-          width="{{ .Width }}"
-          height="{{ .Height }}"
-          {{ if lt .Width 660 }}
-            src="{{ .RelPermalink }}"
-          {{ else }}
-            srcset="
-            {{- (.Resize "330x").RelPermalink }} 330w,
-            {{- (.Resize "660x").RelPermalink }} 660w,
-            {{- (.Resize "1024x").RelPermalink }} 1024w,
-            {{- (.Resize "1320x").RelPermalink }} 2x"
-            src="{{ (.Resize "660x").RelPermalink }}"
-          {{ end }}
-        {{ end }}
-        alt="{{ $altText }}"
-        {{ if $lazyLoad }}
-          loading="lazy"
-        {{ end }}
-      />
-      {{ with $caption }}<figcaption class="text-center">{{ . | markdownify }}</figcaption>{{ end }}
-    </figure>
-  {{ else }}
-    <figure>
-      <img
-        class="mx-auto my-0 rounded-md"
-        src="{{ $url.String }}"
-        alt="{{ $altText }}"
-        {{ if $lazyLoad }}
-          loading="lazy"
-        {{ end }}
-      />
-      {{ with $caption }}<figcaption class="text-center">{{ . | markdownify }}</figcaption>{{ end }}
-    </figure>
-  {{ end }}
-{{ end }}
\ No newline at end of file
+{{ $class := "mx-auto my-0 rounded-md" }}
+
+{{ $file := $url.Path }}
+{{ $img := .Page.Resources.GetMatch $file }}
+{{- if and (not $img) .Page.File }}
+    {{ $path := path.Join .Page.File.Dir $file }}
+    {{ $img = resources.Get $path }}
+{{ end -}}
+
+<figure>
+  {{- with $img -}}
+    {{ partial "pictureDefaults.html" (dict "img" . "alt" $altText "class" $class) }}
+  {{- else -}}
+    <img src="{{ .Destination | safeURL }}" alt="{{ $altText }}" class="{{ $class }}"/>
+  {{- end -}}
+  {{ with $caption }}<figcaption class="text-center">{{ . | markdownify }}</figcaption>{{ end }}
+</figure>
diff --git a/layouts/partials/picture.html b/layouts/partials/picture.html
new file mode 100644
index 00000000..4d5aa7e3
--- /dev/null
+++ b/layouts/partials/picture.html
@@ -0,0 +1,85 @@
+{{ $img := .img }}
+{{ $alt := .alt }}
+{{ $class := .class }}
+{{ $lazy := .lazy }}
+{{ $webp := .webp }}
+{{ $lqip := .lqip }}
+
+{{ with $img }}
+  {{ if (eq .MediaType.SubType "svg") }}
+    {{ $width := ""}}
+    {{ $height := ""}}
+    {{ $svgContent := .Content }}
+    {{ range (findRESubmatch `<svg[^>]*width=["']([.0-9]*)["'a-zA-Z]` $svgContent 1) }}
+      {{ $width = index . 1 }}
+    {{ end }}
+    {{ range (findRESubmatch `<svg[^>]*height=["']([.0-9]*)["'a-zA-Z]` $svgContent 1) }}
+      {{ $height = index . 1 }}
+    {{ end }}
+    {{ if (eq "" $width $height) }}
+      {{ range (findRESubmatch `<svg[^>]*viewBox=["']?([.0-9]*) ([.0-9]*) ([.0-9]*) ([.0-9]*)` $svgContent 1) }}
+        {{ $width = index . 3 }}
+        {{ $height = index . 4 }}
+      {{ end }}
+    {{ end }}
+    {{ if (eq "" $width $height) }}
+      {{ warnf "Can't detect width and height for SVG %s" .RelPermalink }}
+      {{/* do not use lazy without dimensions */}}
+      {{ $lazy = false }}
+    {{ end }}
+    <picture {{ with $class }} class="{{ . }}" {{ end }}>
+      <img
+        src="{{ .RelPermalink }}"
+        {{ with $width }} width="{{ . }}" {{ end }}
+        {{ with $height }} height="{{ . }}" {{ end }}
+        {{ with $class }} class="{{ . }}" {{ end }}
+        {{ with $alt }} alt="{{ . }}" {{ end }}
+        {{ with $lazy }} loading="lazy" decoding="async" {{ end }}
+      >
+    </picture>
+  {{ else }}
+    <picture 
+      {{ with $class }} class="{{ . }}" {{ end }}
+      {{ if $lqip }}
+        {{ $bg := (.Resize "20x webp q20").Content | base64Encode }}
+        style="background-image:url(data:image/webp;base64,{{ $bg }});background-size:cover"
+      {{ end }}
+    >
+    {{ if $webp }}
+      <source 
+        {{ if lt .Width 660 }}
+          {{ with .Resize (printf "%dx%d webp" .Width .Height) }}
+            src="{{ .RelPermalink }}"
+          {{ end }}
+        {{ else }}
+          srcset="
+            {{- (.Resize "330x webp").RelPermalink }} 330w,
+            {{- (.Resize "660x webp").RelPermalink }} 660w,
+            {{- (.Resize "1024x webp").RelPermalink }} 1024w,
+            {{- (.Resize "1320x webp").RelPermalink }} 2x"
+          src="{{ (.Resize "660x webp").RelPermalink }}" 
+        {{ end }}
+        type="image/webp" 
+      />
+    {{ end }}
+      <img
+        src="{{ .RelPermalink }}"
+        width="{{ .Width }}"
+        height="{{ .Height }}"
+        {{ with $class }} class="{{ . }}" {{ end }}
+        {{ with $alt }} alt="{{ . }}" {{ end }}
+        {{ with $lazy }} loading="lazy" decoding="async" {{ end }}
+        {{ if lt .Width 660 }}
+          src="{{ .RelPermalink }}"
+        {{ else }}
+          srcset="
+          {{- (.Resize "330x").RelPermalink }} 330w,
+          {{- (.Resize "660x").RelPermalink }} 660w,
+          {{- (.Resize "1024x").RelPermalink }} 1024w,
+          {{- (.Resize "1320x").RelPermalink }} 2x"
+          src="{{ (.Resize "660x").RelPermalink }}"
+        {{ end }}
+      >
+    </picture>
+  {{ end }}
+{{ end }}
\ No newline at end of file
diff --git a/layouts/partials/pictureDefaults.html b/layouts/partials/pictureDefaults.html
new file mode 100644
index 00000000..1e31be6c
--- /dev/null
+++ b/layouts/partials/pictureDefaults.html
@@ -0,0 +1,7 @@
+{{ $img := .img }}
+{{ $alt := .alt }}
+{{ $class := .class }}
+{{ $lazy := $.Page.Site.Params.enableImageLazyLoading | default true }}
+{{ $webp := $.Page.Site.Params.enableImageWebp | default true }}
+{{ $lqip := false }}
+{{ partial "picture.html" (dict "img" $img "alt" $alt "class" $class "lazy" $lazy "webp" $webp "lqip" $lqip) }}
\ No newline at end of file
diff --git a/layouts/shortcodes/figure.html b/layouts/shortcodes/figure.html
index 7028c6c1..f0d49dfe 100644
--- a/layouts/shortcodes/figure.html
+++ b/layouts/shortcodes/figure.html
@@ -6,45 +6,23 @@
   {{ $caption := .Get "caption" }}
   {{ $href := .Get "href" }}
   {{ $class := .Get "class" }}
+
+  {{ $file := $url.Path }}
+  {{ $img := .Page.Resources.GetMatch $file }}
+  {{- if and (not $img) .Page.File }}
+    {{ $path := path.Join .Page.File.Dir $file }}
+    {{ $img = resources.Get $path }}
+  {{ end -}}
+
   <figure{{ with $class }} class="{{ . }}"{{ end }}>
     {{ with $href }}<a href="{{ . }}">{{ end }}
-    <img
-      class="mx-auto my-0 rounded-md"
-      alt="{{ $altText }}"
-      {{ if .Site.Params.enableImageLazyLoading | default true }}
-        loading="lazy"
-      {{ end }}
-      {{ if findRE "^https?" $url.Scheme }}
-        src="{{ $url.String }}"
-      {{ else }}
-        {{ $resource := "" }}
-        {{ if $.Page.Resources.GetMatch ($url.String) }}
-          {{ $resource = $.Page.Resources.GetMatch ($url.String) }}
-        {{ else if resources.GetMatch ($url.String) }}
-          {{ $resource = resources.Get ($url.String) }}
-        {{ end }}
-        {{ with $resource }}
-          {{ if eq .MediaType.SubType "svg" }}
-            src="{{ .RelPermalink }}"
-          {{ else }}
-            width="{{ .Width }}"
-            height="{{ .Height }}"
-            {{ if lt .Width 660 }}
-              src="{{ .RelPermalink }}"
-            {{ else }}
-              srcset="
-              {{- (.Resize "330x").RelPermalink }} 330w,
-              {{- (.Resize "660x").RelPermalink }} 660w,
-              {{- (.Resize "1024x").RelPermalink }} 1024w,
-              {{- (.Resize "1320x").RelPermalink }} 2x"
-              src="{{ (.Resize "660x").RelPermalink }}"
-            {{ end }}
-          {{ end }}
-        {{ else }}
-          src="{{ $url.String }}"
-        {{ end }}
-      {{ end }}
-    />
+
+    {{- with $img -}}
+      {{ partial "pictureDefaults.html" (dict "img" . "alt" $altText "class" $class) }}
+    {{- else -}}
+      <img src="{{ $url.String }}" alt="{{ $altText }}" class="{{ $class }}"/>
+    {{- end -}}
+
     {{ with $href }}</a>{{ end }}
     {{ with $caption }}<figcaption class="text-center">{{ . | markdownify }}</figcaption>{{ end }}
   </figure>

From 6f0d70ee3635b95f19587a9ba5f1dea577712c1c Mon Sep 17 00:00:00 2001
From: stereobooster <stereobooster@gmail.com>
Date: Tue, 31 Oct 2023 18:14:03 +0100
Subject: [PATCH 2/5] integrate in single.html

---
 layouts/_default/single.html | 22 +++-------------------
 1 file changed, 3 insertions(+), 19 deletions(-)

diff --git a/layouts/_default/single.html b/layouts/_default/single.html
index 340e95a1..90e41daa 100644
--- a/layouts/_default/single.html
+++ b/layouts/_default/single.html
@@ -15,25 +15,9 @@
       </div>
       {{ with $feature }}
         <div class="prose">
-          <img
-            class="mb-6 -mt-4 rounded-md"
-            {{ if eq .MediaType.SubType "svg" }}
-              src="{{ .RelPermalink }}"
-            {{ else }}
-              width="{{ .Width }}"
-              height="{{ .Height }}"
-              {{ if lt .Width 660 }}
-                src="{{ .RelPermalink }}"
-              {{ else }}
-                srcset="
-                {{- (.Resize "330x").RelPermalink }} 330w,
-                {{- (.Resize "660x").RelPermalink }} 660w,
-                {{- (.Resize "1024x").RelPermalink }} 1024w,
-                {{- (.Resize "1320x").RelPermalink }} 2x"
-              {{ end }}
-            {{ end }}
-            alt="{{ $.Params.featureAlt | default $.Params.coverAlt | default "" }}"
-          />
+          {{ $altText := $.Params.featureAlt | default $.Params.coverAlt | default "" }}
+          {{ $class := "mb-6 -mt-4 rounded-md" }}
+          {{ partial "pictureDefaults.html" (dict "img" . "alt" $altText "class" $class) }}
           {{ with $.Params.coverCaption }}
             <figcaption class="mb-6 -mt-3 text-center">{{ . | markdownify }}</figcaption>
           {{ end }}

From b592a81d46e48381c166c80d6b18798c26bf6a4b Mon Sep 17 00:00:00 2001
From: stereobooster <stereobooster@gmail.com>
Date: Sun, 26 Nov 2023 01:21:36 +0100
Subject: [PATCH 3/5] do not upscale images in picture shortcode

---
 layouts/partials/picture.html | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/layouts/partials/picture.html b/layouts/partials/picture.html
index 4d5aa7e3..47ffe103 100644
--- a/layouts/partials/picture.html
+++ b/layouts/partials/picture.html
@@ -54,9 +54,13 @@
         {{ else }}
           srcset="
             {{- (.Resize "330x webp").RelPermalink }} 330w,
-            {{- (.Resize "660x webp").RelPermalink }} 660w,
-            {{- (.Resize "1024x webp").RelPermalink }} 1024w,
-            {{- (.Resize "1320x webp").RelPermalink }} 2x"
+            {{- (.Resize "660x webp").RelPermalink }} 660w
+            {{ if gt .Width 1024 }}
+              ,{{ (.Resize "1024x webp").RelPermalink }} 1024w
+            {{ end }}
+            {{ if gt .Width 1320 }}
+              ,{{ (.Resize "1320x webp").RelPermalink }} 2x
+            {{ end }}"
           src="{{ (.Resize "660x webp").RelPermalink }}" 
         {{ end }}
         type="image/webp" 
@@ -74,9 +78,13 @@
         {{ else }}
           srcset="
           {{- (.Resize "330x").RelPermalink }} 330w,
-          {{- (.Resize "660x").RelPermalink }} 660w,
-          {{- (.Resize "1024x").RelPermalink }} 1024w,
-          {{- (.Resize "1320x").RelPermalink }} 2x"
+          {{- (.Resize "660x").RelPermalink }} 660w
+          {{ if gt .Width 1024 }}
+            ,{{ (.Resize "1024x").RelPermalink }} 1024w
+          {{ end }}
+          {{ if gt .Width 1320 }}
+            ,{{ (.Resize "1320x").RelPermalink }} 2x
+          {{ end }}"
           src="{{ (.Resize "660x").RelPermalink }}"
         {{ end }}
       >

From 06195bc37983809f399c0cf074ffdc1871d2b13a Mon Sep 17 00:00:00 2001
From: stereobooster <stereobooster@gmail.com>
Date: Sun, 26 Nov 2023 02:02:09 +0100
Subject: [PATCH 4/5] use original image as backup for srcset

---
 layouts/partials/picture.html | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/layouts/partials/picture.html b/layouts/partials/picture.html
index 47ffe103..9056f224 100644
--- a/layouts/partials/picture.html
+++ b/layouts/partials/picture.html
@@ -57,9 +57,17 @@
             {{- (.Resize "660x webp").RelPermalink }} 660w
             {{ if gt .Width 1024 }}
               ,{{ (.Resize "1024x webp").RelPermalink }} 1024w
+            {{ else }}
+              {{ with .Resize (printf "%dx%d webp" .Width .Height) }}
+                ,{{ .RelPermalink }} {{ .Width }}w
+              {{ end }}
             {{ end }}
             {{ if gt .Width 1320 }}
               ,{{ (.Resize "1320x webp").RelPermalink }} 2x
+            {{ else }}
+              {{ with .Resize (printf "%dx%d webp" .Width .Height) }}
+                ,{{ .RelPermalink }} {{ .Width }}w
+              {{ end }}
             {{ end }}"
           src="{{ (.Resize "660x webp").RelPermalink }}" 
         {{ end }}
@@ -81,9 +89,13 @@
           {{- (.Resize "660x").RelPermalink }} 660w
           {{ if gt .Width 1024 }}
             ,{{ (.Resize "1024x").RelPermalink }} 1024w
+          {{ else }}
+            ,{{ .RelPermalink }} {{ .Width }}w
           {{ end }}
           {{ if gt .Width 1320 }}
             ,{{ (.Resize "1320x").RelPermalink }} 2x
+          {{ else }}
+            ,{{ .RelPermalink }} {{ .Width }}w
           {{ end }}"
           src="{{ (.Resize "660x").RelPermalink }}"
         {{ end }}

From 954fd7fac91614c69ee8c077292729685c649d04 Mon Sep 17 00:00:00 2001
From: stereobooster <stereobooster@gmail.com>
Date: Sun, 26 Nov 2023 02:23:34 +0100
Subject: [PATCH 5/5] potential solution to screenshot

---
 layouts/_default/_markup/render-image.html | 10 +++++++++-
 layouts/partials/picture.html              | 11 +++++++++--
 layouts/partials/pictureDefaults.html      |  3 ++-
 layouts/shortcodes/screenshot.html         | 21 ++++++++++-----------
 4 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html
index 2e7a5b53..7a7e18a5 100644
--- a/layouts/_default/_markup/render-image.html
+++ b/layouts/_default/_markup/render-image.html
@@ -10,9 +10,17 @@
     {{ $img = resources.Get $path }}
 {{ end -}}
 
+{{/* https://github.com/gohugoio/hugo/pull/10666/files */}}
+{{- $params := $url.Query -}}
+{{- $x2Param := $params.Get "x2" -}}
+{{- $x2 := false -}}
+{{- if eq $x2Param "true" -}}
+    {{- $x2 = true  -}}
+{{- end -}}
+
 <figure>
   {{- with $img -}}
-    {{ partial "pictureDefaults.html" (dict "img" . "alt" $altText "class" $class) }}
+    {{ partial "pictureDefaults.html" (dict "img" . "alt" $altText "class" $class "x2" $x2) }}
   {{- else -}}
     <img src="{{ .Destination | safeURL }}" alt="{{ $altText }}" class="{{ $class }}"/>
   {{- end -}}
diff --git a/layouts/partials/picture.html b/layouts/partials/picture.html
index 9056f224..33553667 100644
--- a/layouts/partials/picture.html
+++ b/layouts/partials/picture.html
@@ -4,6 +4,7 @@
 {{ $lazy := .lazy }}
 {{ $webp := .webp }}
 {{ $lqip := .lqip }}
+{{ $x2 := .x2 | default false }}
 
 {{ with $img }}
   {{ if (eq .MediaType.SubType "svg") }}
@@ -45,6 +46,12 @@
         style="background-image:url(data:image/webp;base64,{{ $bg }});background-size:cover"
       {{ end }}
     >
+    {{ $width := .Width }}
+    {{ $height := .Height }}
+    {{ if $x2 }}
+      {{ $width = div .Width 2 }}
+      {{ $height = div .Height 2 }}
+    {{ end }}
     {{ if $webp }}
       <source 
         {{ if lt .Width 660 }}
@@ -76,8 +83,8 @@
     {{ end }}
       <img
         src="{{ .RelPermalink }}"
-        width="{{ .Width }}"
-        height="{{ .Height }}"
+        width="{{ $width }}"
+        height="{{ $height }}"
         {{ with $class }} class="{{ . }}" {{ end }}
         {{ with $alt }} alt="{{ . }}" {{ end }}
         {{ with $lazy }} loading="lazy" decoding="async" {{ end }}
diff --git a/layouts/partials/pictureDefaults.html b/layouts/partials/pictureDefaults.html
index 1e31be6c..01eb0986 100644
--- a/layouts/partials/pictureDefaults.html
+++ b/layouts/partials/pictureDefaults.html
@@ -4,4 +4,5 @@
 {{ $lazy := $.Page.Site.Params.enableImageLazyLoading | default true }}
 {{ $webp := $.Page.Site.Params.enableImageWebp | default true }}
 {{ $lqip := false }}
-{{ partial "picture.html" (dict "img" $img "alt" $alt "class" $class "lazy" $lazy "webp" $webp "lqip" $lqip) }}
\ No newline at end of file
+{{ $x2 := .x2 }}
+{{ partial "picture.html" (dict "img" $img "alt" $alt "class" $class "lazy" $lazy "webp" $webp "lqip" $lqip "x2" $x2) }}
\ No newline at end of file
diff --git a/layouts/shortcodes/screenshot.html b/layouts/shortcodes/screenshot.html
index 653e1fd7..28025748 100644
--- a/layouts/shortcodes/screenshot.html
+++ b/layouts/shortcodes/screenshot.html
@@ -4,17 +4,16 @@
     {{- if .Get "href" -}}
       <a href="{{ .Get "href" }}">
     {{- end -}}
-    <img src="{{ $image.RelPermalink }}"
-      {{- if or (.Get "alt") (.Get "caption") }}
-        alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" | markdownify | plainify }}{{ end }}"
-      {{- end -}}
-      {{ if .Site.Params.enableImageLazyLoading | default true }}
-        loading="lazy"
-      {{ end }}
-      width="100%"
-      height="auto"
-      style="max-width:{{ div $image.Width 2 }}px; max-height:{{ div $image.Height 2 }}px;"
-    />
+
+    {{ $altText := "" }}
+    {{ with .Get "alt" }}
+      {{ $altText = . }}
+    {{ else }}
+      {{ $altText = (.Get "caption") | markdownify | plainify }}
+    {{ end }}
+
+    {{ partial "pictureDefaults.html" (dict "img" $image "alt" $altText "x2" true) }}
+
     {{- if .Get "href" }}</a>{{ end -}}
     {{- if .Get "caption" -}}
       <figcaption>