First commit
Some checks failed
Blowfish Docs Deploy / build (push) Has been cancelled
Blowfish Docs Deploy / deploy (push) Has been cancelled
Test Build / Build Example Site (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Update Hugo version / updateBlowfish (push) Has been cancelled

Delete exampleSite
Add initial content, images & docker-compose.yml
Use extend-head.html for analytics
Set remote url to gitea.novicelab.io
Remove original .git due to "shallow update not allowed" error
This commit is contained in:
2026-03-14 14:37:54 +00:00
commit 6330092560
508 changed files with 36938 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
{{ $id := delimit (slice "accordion" (partial "functions/uid.html" .)) "-" }}
{{ $mode := .Get "mode" | default "collapse" }}
{{ $separated := .Get "separated" | default false }}
{{ $isSeparated := or (eq $separated true) (eq $separated "true") }}
<div
id="{{ $id }}"
class="{{ if $isSeparated }}space-y-2{{ else }}border border-neutral-200 dark:border-neutral-700 rounded-lg overflow-hidden{{ end }}"
data-accordion="{{ $mode }}"
data-accordion-separated="{{ $isSeparated }}"
>
{{- .Inner -}}
</div>
{{ if $isSeparated }}
<style>
#{{ $id }} > details + details {
margin-top: 0.5rem;
}
</style>
{{ else }}
<style>
#{{ $id }} > details + details {
border-top: 1px solid rgb(var(--color-neutral-200));
}
.dark #{{ $id }} > details + details {
border-top-color: rgb(var(--color-neutral-700));
}
</style>
{{ end }}
{{ if eq $mode "collapse" }}
<script>
(() => {
const root = document.getElementById("{{ $id }}");
if (!root) return;
const items = root.querySelectorAll("details[data-accordion-item]");
items.forEach((item) => {
item.addEventListener("toggle", () => {
if (!item.open) return;
items.forEach((other) => {
if (other !== item) other.removeAttribute("open");
});
});
});
})();
</script>
{{ end }}

View File

@@ -0,0 +1,37 @@
{{ $parent := .Parent }}
{{ $separated := false }}
{{ if $parent }}
{{ $separated = $parent.Get "separated" | default false }}
{{ end }}
{{ $isSeparated := or (eq $separated true) (eq $separated "true") }}
{{ $title := .Get "title" | default (.Get "header") }}
{{ $icon := .Get "icon" }}
{{ $md := .Get "md" | default true }}
{{ $open := .Get "open" | default false }}
{{ $isOpen := or (eq $open true) (eq $open "true") }}
<details
class="{{ if $isSeparated }}rounded-lg border border-neutral-200 dark:border-neutral-700 overflow-hidden{{ else }}border-none{{ end }}"
data-accordion-item
{{ if $isOpen }}open{{ end }}
>
<summary class="flex w-full cursor-pointer items-center justify-between gap-4 px-4 py-3 text-left text-lg font-semibold text-neutral-900 dark:text-neutral-100">
<span class="flex items-center gap-2">
{{ with $icon }}
{{ partial "icon.html" . }}
{{ end }}
<span>{{ $title }}</span>
</span>
<span>
{{ partial "icon" "chevron-down" }}
</span>
</summary>
<div class="px-4 pb-4 text-neutral-700 dark:text-neutral-300">
{{ if $md }}
{{- .Inner | markdownify -}}
{{ else }}
{{- .Inner -}}
{{ end }}
</div>
</details>

View File

@@ -0,0 +1,37 @@
{{ if .IsNamedParams }}
{{ $.Scratch.Set "icon" (default "triangle-exclamation" (.Get "icon") ) }}
{{ $.Scratch.Set "cardColor" (.Get "cardColor") }}
{{ $.Scratch.Set "iconColor" (.Get "iconColor") }}
{{ $.Scratch.Set "textColor" (.Get "textColor") }}
{{ else }}
{{ $.Scratch.Set "icon" (default "triangle-exclamation" (.Get 0) ) }}
{{ end }}
<div
{{ if not ($.Scratch.Get "cardColor") }}
class="flex px-4 py-3 rounded-md shadow bg-primary-100 dark:bg-primary-900"
{{ else }}
class="flex px-4 py-3 rounded-md shadow" style="background-color: {{ $.Scratch.Get "cardColor" }}"
{{ end }}
>
<span
{{ if not ($.Scratch.Get "iconColor") }}
class="text-primary-400 pe-3 flex items-center"
{{ else }}
class="pe-3 flex items-center" style="color: {{ $.Scratch.Get "iconColor" }}"
{{ end }}
>
{{ partial "icon.html" ($.Scratch.Get "icon") }}
</span>
<span
{{ if not ($.Scratch.Get "textColor") }}
class="dark:text-neutral-300"
{{ else }}
style="color: {{ $.Scratch.Get "textColor" }}"
{{ end }}
>
{{- .Inner | markdownify -}}
</span>
</div>

View File

@@ -0,0 +1,13 @@
{{ $link := .Get "link" }}
{{ $showSummary := .Get "showSummary" }}
{{ $compactSummary := .Get "compactSummary" | default false }}
{{ $target := .Page }}
{{ if ne $link .Page.RelPermalink }}
{{ $target = index (first 1 (where .Site.AllPages "RelPermalink" $link)) 0 }}
{{ end }}
{{ if $target }}
<section class="space-y-10 w-full">
{{ $context := dict "target" $target "showSummary" $showSummary "compactSummary" $compactSummary }}
{{ partial "article-link/_shortcode.html" $context }}
</section>
{{ end }}

View File

@@ -0,0 +1 @@
{{ partial "badge.html" .Inner }}

View File

@@ -0,0 +1,8 @@
<a
class="!rounded-md bg-primary-600 px-4 py-2 !text-neutral !no-underline hover:!bg-primary-500 dark:bg-primary-800 dark:hover:!bg-primary-700"
{{ with .Get "href" }}href="{{ . }}"{{ end }}
{{ with .Get "target" }}target="{{ . }}"{{ end }}
{{ with .Get "rel" }}rel="{{ . }}"{{ end }}
role="button">
{{ .Inner }}
</a>

View File

@@ -0,0 +1,145 @@
{{ $id := delimit (slice "carousel" (partial "functions/uid.html" .) (now.UnixNano)) "-" }}
{{ $aspect := (split (.Get "aspectRatio") "-") }}
{{ $aspectx := default "16" (index $aspect 0) }}
{{ $aspecty := default "9" (index $aspect 1) }}
{{ $interval := default "2000" (.Get "interval") }}
{{ $page := .Page.Resources }}
{{ $imagesTemp := .Get "images" }}
{{ $imagesTemp = strings.TrimPrefix "{" $imagesTemp }}
{{ $imagesTemp = strings.TrimSuffix "}" $imagesTemp }}
{{ $imagesTemp := strings.Split $imagesTemp "," }}
{{ $images := slice }}
{{ range $imagesTemp }}
{{ if or (strings.HasPrefix . "http:") (strings.HasPrefix . "https:") }}
{{ $images = $images | append (dict "resource" (resources.GetRemote .) "key" .) }}
{{ else }}
{{ range ($page.Match .) }}
{{ $images = $images | append (dict "resource" . "key" .Name) }}
{{ end }}
{{ end }}
{{ end }}
{{ $captionsParam := .Get "captions" }}
{{ $captions := dict }}
{{ if $captionsParam }}
{{ $captionsTemp := strings.TrimPrefix "{" $captionsParam }}
{{ $captionsTemp = strings.TrimSuffix "}" $captionsTemp }}
{{ range (strings.Split $captionsTemp ",") }}
{{ $pair := strings.Split . ":" }}
{{ if ge (len $pair) 2 }}
{{ $key := strings.TrimSpace (index $pair 0) }}
{{ $value := strings.TrimSpace (delimit (after 1 $pair) ":") }}
{{ $captions = merge $captions (dict $key $value) }}
{{ end }}
{{ end }}
{{ end }}
{{ if not .Parent }}<div class="width-patch"></div>{{ end }}
<div
id="{{ $id }}"
class="relative"
data-twe-carousel-init
data-twe-ride="carousel"
data-twe-interval="{{ $interval }}">
<div
class="absolute right-0 bottom-0 left-0 z-2 mx-[15%] mb-10 flex list-none justify-center p-0"
data-twe-carousel-indicators>
{{ $num := 0 }}
{{ range $images }}
<button
type="button"
data-twe-target="#{{ $id }}"
data-twe-slide-to="{{ $num }}"
{{ if eq $num 0 }}data-twe-carousel-active aria-current="true"{{ end }}
class="mx-[3px] box-content h-[3px] w-[30px] flex-initial cursor-pointer border-0 border-y-[10px] border-solid border-transparent bg-neutral bg-clip-padding p-0 -indent-[999px] opacity-50 transition-opacity duration-[600ms] ease-[cubic-bezier(0.25,0.1,0.25,1.0)] motion-reduce:transition-none"
aria-label="Slide {{ $num }}"></button>
{{ $num = add $num 1 }}
{{ end }}
</div>
<div
class="relative w-full after:clear-both after:block after:content-['']"
style="overflow-x: clip; overflow-y: visible;">
{{ range $index, $image := $images }}
{{ $hiddenClass := cond (eq $index 0) "" "hidden" }}
{{ $resource := index $image "resource" }}
{{ $key := index $image "key" }}
{{ $caption := "" }}
{{ $candidates := slice }}
{{ if $resource }}
{{ $candidates = $candidates | append $resource.Name (path.Base $resource.Name) $resource.RelPermalink (path.Base $resource.RelPermalink) }}
{{ end }}
{{ if $key }}
{{ $candidates = $candidates | append $key (path.Base $key) }}
{{ end }}
{{ range $candidates }}
{{ if and (not $caption) . }}
{{ with (index $captions .) }}{{ $caption = . }}{{ end }}
{{ end }}
{{ end }}
<div
class="relative float-left -mr-[100%] {{ $hiddenClass }} w-full transition-transform ease-in-out motion-reduce:transition-none"
data-twe-carousel-item
style="transition-duration: {{ $interval }}ms;"
{{ if eq $index 0 }}data-twe-carousel-active{{ end }}>
<div class="single_hero_background relative overflow-hidden" style="aspect-ratio: {{ $aspectx }} / {{ $aspecty }};">
<img
src="{{ $resource.RelPermalink }}"
class="block absolute top-0 object-cover w-full h-full not-prose nozoom"
alt="carousel image {{ add $index 1 }}">
</div>
{{ if $caption }}
<figcaption
class="absolute left-0 right-0"
style="top: calc(100%);"
>{{ $caption | markdownify }}</figcaption>
{{ end }}
</div>
{{ end }}
</div>
<button
class="absolute top-0 bottom-0 left-0 z-2 flex w-[15%] items-center justify-center border-0 bg-none p-0 text-center opacity-50 transition-opacity duration-150 ease-[cubic-bezier(0.25,0.1,0.25,1.0)] hover:no-underline hover:opacity-90 hover:outline-none focus:no-underline focus:opacity-90 focus:outline-none motion-reduce:transition-none"
type="button"
data-twe-target="#{{ $id }}"
data-twe-slide="prev">
<span class="inline-block h-8 w-8">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="4.5"
stroke="currentColor"
class="h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
</svg>
</span>
<span
class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
>Previous</span
>
</button>
<button
class="absolute top-0 bottom-0 right-0 z-[1] flex w-[15%] items-center justify-center border-0 bg-none p-0 text-center opacity-50 transition-opacity duration-150 ease-[cubic-bezier(0.25,0.1,0.25,1.0)] hover:no-underline hover:opacity-90 hover:outline-none focus:no-underline focus:opacity-90 focus:outline-none motion-reduce:transition-none"
type="button"
data-twe-target="#{{ $id }}"
data-twe-slide="next">
<span class="inline-block h-8 w-8">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="4.5"
stroke="currentColor"
class="h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</span>
<span
class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
>Next</span
>
</button>
</div>

View File

@@ -0,0 +1,12 @@
{{ $id := delimit (slice "chart" (partial "functions/uid.html" .)) "-" }}
<div class="chart">
<canvas id="{{ $id }}"></canvas>
<script type="text/javascript">
window.addEventListener("DOMContentLoaded", (event) => {
const ctx = document.getElementById("{{ $id }}");
const chart = new Chart(ctx, {
{{ .Inner | safeJS }}
});
});
</script>
</div>

View File

@@ -0,0 +1,69 @@
{{ $id := delimit (slice "codeberg" (partial "functions/uid.html" .)) "-" }}
{{- $codebergURL := print "https://codeberg.org/api/v1/repos/" (.Get "repo") -}}
{{- $repoColors := .Site.Data.repoColors -}}
{{- $codebergData := dict -}}
{{- with try (resources.GetRemote $codebergURL) -}}
{{- with .Err -}}
{{- warnf "codeberg shortcode: failed to fetch remote resource from %q: %s" $codebergURL $.Position -}}
{{- else with .Value -}}
{{- $codebergData = . | transform.Unmarshal -}}
{{- else -}}
{{- warnf "codeberg shortcode: unable to get remote resource from %q: %s" $codebergURL $.Position -}}
{{- end -}}
{{- end -}}
{{- with $codebergData -}}
<div class="codeberg-card-wrapper">
<a id="{{ $id }}" target="_blank" href="{{ .html_url }}" class="cursor-pointer">
<div
class="w-full md:w-auto pt-3 p-5 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl">
<div class="flex items-center">
<span class="text-2xl text-neutral-800 dark:text-neutral me-2">
{{ partial "icon.html" "codeberg" }}
</span>
<div
id="{{ $id }}-full_name"
class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral">
{{ .full_name | markdownify }}
</div>
</div>
<p id="{{ $id }}-description" class="m-0 mt-2 text-md text-neutral-800 dark:text-neutral">
{{ .description | markdownify }}
</p>
<div class="m-0 mt-2 flex items-center">
<span class="mr-1 inline-block h-3 w-3 rounded-full language-dot" data-language="{{ .language | default "default" }}"></span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ if .language }}{{ .language }}{{ else }}null{{ end }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "star" }}
</span>
<div id="{{ $id }}-stars_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .stars_count }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "fork" }}
</span>
<div id="{{ $id }}-forks_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .forks_count }}
</div>
</div>
</div>
{{ $fetchRepo := resources.Get "js/fetch-repo.js" }}
{{ $fetchRepo = $fetchRepo | resources.Minify | resources.Fingerprint ($.Site.Params.fingerprintAlgorithm | default "sha512") }}
<script
async
type="text/javascript"
src="{{ $fetchRepo.RelPermalink }}"
integrity="{{ $fetchRepo.Data.Integrity }}"
data-repo-url="{{ $codebergURL }}"
data-repo-id="{{ $id }}"></script>
</a>
</div>
{{- else -}}
{{ warnf "codeberg shortcode: unable to fetch %q: %s" $codebergURL .Position }}
{{- end -}}

View File

@@ -0,0 +1,27 @@
{{ $url := .Get "url" }}
{{ $type := .Get "type" }}
{{ $startLine := .Get "startLine" | default 1 | int }}
{{ $startLine = sub $startLine 1 }}
{{ $endLine := .Get "endLine" | default -1 | int }}
{{ $selectedLines := slice }}
{{ with resources.GetRemote (urls.Parse $url) }}
{{ $lines := split .Content "\n" }}
{{ $totalLine := $lines | len }}
{{ if ne $endLine -1 }}
{{ $endLine = math.Min $endLine $totalLine }}
{{ else }}
{{ $endLine = $totalLine }}
{{ end }}
{{ if gt $startLine $endLine }}
{{ errorf "codeimporter shortcode: startLine is greater than endLine" . }}
{{ end }}
{{ $selectedLines := first $endLine $lines }}
{{ $selectedLines = after $startLine $selectedLines }}
{{ $codeBlock := printf "```%s\n%s\n```" $type (delimit $selectedLines "\n") }}
{{ $codeBlock | markdownify }}
{{ else }}
{{ warnf "codeimporter shortcode: unable to fetch %q: %s" $url .Position }}
{{ end }}

View File

@@ -0,0 +1,56 @@
{{ $disableImageOptimization := .Site.Params.disableImageOptimization | default false }}
{{ if .Get "default" }}
{{ partial "hugo-embedded/shortcodes/figure-default.html" . }}
{{ else }}
{{- $url := urls.Parse (.Get "src") }}
{{- $altText := .Get "alt" }}
{{- $caption := .Get "caption" }}
{{- $href := .Get "href" }}
{{- $class := .Get "class" }}
{{- $figureClass := .Get "figureClass" }}
{{- $target := .Get "target" | default "_blank" }}
{{- $nozoom := .Get "nozoom" | default false -}}
<figure{{ with $figureClass }} class="{{ . }}"{{ end }}>
{{- with $href }}<a href="{{ . }}" {{ with $target }}target="{{ . }}"{{ end }} class="inline-block">{{ end -}}
{{- if findRE "^https?" $url.Scheme }}
<img class="my-0 rounded-md{{ with $nozoom }} nozoom{{ end }}{{ with $class }} {{ . }}{{ end }}" src="{{ $url.String }}" alt="{{ $altText }}" />
{{- 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 or $disableImageOptimization (eq .MediaType.SubType "svg")}}
<img
class="my-0 rounded-md{{ with $nozoom }} nozoom{{ end }}{{ with $class }} {{ . }}{{ end }}"
src="{{ .RelPermalink }}"
alt="{{ $altText }}"
/>
{{- else }}
<img
class="my-0 rounded-md{{ with $nozoom }} nozoom{{ end }}{{ with $class }} {{ . }}{{ end }}"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="{{ $altText }}"
{{ with .Width }}width="{{ . }}"{{ end }}
{{ with .Height }}height="{{ . }}"{{ end }}
src="{{ (.Resize "800x").RelPermalink }}"
srcset="
{{- (.Resize "800x").RelPermalink }} 800w,
{{- (.Resize "1280x").RelPermalink }} 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="{{ .RelPermalink }}"
/>
{{- end }}
{{- else }}
<img class="my-0 rounded-md{{ with $nozoom }} nozoom{{ end }}{{ with $class }} {{ . }}{{ end }}" src="{{ $url.String }}" alt="{{ $altText }}" />
{{- end }}
{{- end }}
{{ if $href }}</a>{{ end }}
{{ with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
</figure>
{{- end -}}

View File

@@ -0,0 +1,69 @@
{{ $id := delimit (slice "forgejo" (partial "functions/uid.html" .)) "-" }}
{{- $forgejoURL := print (.Get "server" | default .Site.Params.forgejoDefaultServer) "/api/v1/repos/" (.Get "repo") -}}
{{- $repoColors := .Site.Data.repoColors -}}
{{- $forgejoData := dict -}}
{{- with try (resources.GetRemote $forgejoURL) -}}
{{- with .Err -}}
{{- warnf "forgejo shortcode: failed to fetch remote resource from %q: %s" $forgejoURL $.Position -}}
{{- else with .Value -}}
{{- $forgejoData = . | transform.Unmarshal -}}
{{- else -}}
{{- warnf "forgejo shortcode: unable to get remote resource from %q: %s" $forgejoURL $.Position -}}
{{- end -}}
{{- end -}}
{{- with $forgejoData -}}
<div class="forgejo-card-wrapper">
<a id="{{ $id }}" target="_blank" href="{{ .html_url }}" class="cursor-pointer">
<div
class="w-full md:w-auto pt-3 p-5 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl">
<div class="flex items-center">
<span class="text-2xl text-neutral-800 dark:text-neutral me-2">
{{ partial "icon.html" "forgejo" }}
</span>
<div
id="{{ $id }}-full_name"
class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral">
{{ .full_name | markdownify }}
</div>
</div>
<p id="{{ $id }}-description" class="m-0 mt-2 text-md text-neutral-800 dark:text-neutral">
{{ .description | markdownify }}
</p>
<div class="m-0 mt-2 flex items-center">
<span class="mr-1 inline-block h-3 w-3 rounded-full language-dot" data-language="{{ .language | default "default" }}"></span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ if .language }}{{ .language }}{{ else }}null{{ end }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "star" }}
</span>
<div id="{{ $id }}-stars_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .stars_count }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "fork" }}
</span>
<div id="{{ $id }}-forks_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .forks_count }}
</div>
</div>
</div>
{{ $fetchRepo := resources.Get "js/fetch-repo.js" }}
{{ $fetchRepo = $fetchRepo | resources.Minify | resources.Fingerprint ($.Site.Params.fingerprintAlgorithm | default "sha512") }}
<script
async
type="text/javascript"
src="{{ $fetchRepo.RelPermalink }}"
integrity="{{ $fetchRepo.Data.Integrity }}"
data-repo-url="{{ $forgejoURL }}"
data-repo-id="{{ $id }}"></script>
</a>
</div>
{{- else -}}
{{ warnf "forgejo shortcode: unable to fetch %q: %s" $forgejoURL .Position }}
{{- end -}}

View File

@@ -0,0 +1,31 @@
{{ $id := delimit (slice "gallery" (partial "functions/uid.html" .)) "-" -}}
{{ $content := .Inner -}}
{{/* find all img tags */}}
{{ range findRE `<img\s+[^>]*>` $content -}}
{{ $imgTag := . -}}
{{/* extract src attribute */}}
{{ with findRESubmatch `src=['"]([^'"]+)['"]` $imgTag -}}
{{ $srcAttr := index (index . 0) 0 -}}
{{ $srcValue := index (index . 0) 1 -}}
{{ $srcValueFinal := $srcValue -}}
{{ if or (hasPrefix $srcValue "http://") (hasPrefix $srcValue "https://") -}}
{{ with resources.GetRemote $srcValue -}}{{ $srcValueFinal = .RelPermalink -}}{{ end -}}
{{ else -}}
{{ with $.Page.Resources.GetMatch $srcValue -}}
{{ $srcValueFinal = .RelPermalink -}}
{{ else -}}
{{ with resources.GetMatch $srcValue -}}{{ $srcValueFinal = .RelPermalink -}}{{ end -}}
{{ end -}}
{{ end -}}
{{ $newTag := replace $imgTag $srcAttr (printf `src="%s"` $srcValueFinal) -}}
{{ $content = replace $content $imgTag $newTag -}}
{{ end -}}
{{ end -}}
{{ if not .Parent }}<div class="width-patch"></div>{{ end }}
<div id="{{- $id -}}" class="gallery">
{{ $content | safeHTML -}}
</div>

View File

@@ -0,0 +1,3 @@
<script src="https://gist.github.com/{{- index .Params 0 -}}/{{- index .Params 1 -}}.js{{- if len .Params | eq 3 -}}
?file={{- index .Params 2 -}}
{{- end -}}"></script>

View File

@@ -0,0 +1,69 @@
{{ $id := delimit (slice "gitea" (partial "functions/uid.html" .)) "-" }}
{{- $giteaURL := print (.Get "server" | default .Site.Params.giteaDefaultServer) "/api/v1/repos/" (.Get "repo") -}}
{{- $repoColors := .Site.Data.repoColors -}}
{{- $giteaData := dict -}}
{{- with try (resources.GetRemote $giteaURL) -}}
{{- with .Err -}}
{{- warnf "gitea shortcode: failed to fetch remote resource from %q: %s" $giteaURL $.Position -}}
{{- else with .Value -}}
{{- $giteaData = . | transform.Unmarshal -}}
{{- else -}}
{{- warnf "gitea shortcode: unable to get remote resource from %q: %s" $giteaURL $.Position -}}
{{- end -}}
{{- end -}}
{{- with $giteaData -}}
<div class="gitea-card-wrapper">
<a id="{{ $id }}" target="_blank" href="{{ .html_url }}" class="cursor-pointer">
<div
class="w-full md:w-auto pt-3 p-5 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl">
<div class="flex items-center">
<span class="text-2xl text-neutral-800 dark:text-neutral me-2">
{{ partial "icon.html" "gitea" }}
</span>
<div
id="{{ $id }}-full_name"
class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral">
{{ .full_name | markdownify }}
</div>
</div>
<p id="{{ $id }}-description" class="m-0 mt-2 text-md text-neutral-800 dark:text-neutral">
{{ .description | markdownify }}
</p>
<div class="m-0 mt-2 flex items-center">
<span class="mr-1 inline-block h-3 w-3 rounded-full language-dot" data-language="{{ .language | default "default" }}"></span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ if .language }}{{ .language }}{{ else }}null{{ end }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "star" }}
</span>
<div id="{{ $id }}-stars_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .stars_count }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "fork" }}
</span>
<div id="{{ $id }}-forks_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .forks_count }}
</div>
</div>
</div>
{{ $fetchRepo := resources.Get "js/fetch-repo.js" }}
{{ $fetchRepo = $fetchRepo | resources.Minify | resources.Fingerprint ($.Site.Params.fingerprintAlgorithm | default "sha512") }}
<script
async
type="text/javascript"
src="{{ $fetchRepo.RelPermalink }}"
integrity="{{ $fetchRepo.Data.Integrity }}"
data-repo-url="{{ $giteaURL }}"
data-repo-id="{{ $id }}"></script>
</a>
</div>
{{- else -}}
{{ warnf "gitea shortcode: unable to fetch %q: %s" $giteaURL .Position }}
{{- end -}}

View File

@@ -0,0 +1,83 @@
{{ $id := delimit (slice "github" (partial "functions/uid.html" .)) "-" }}
{{- $githubURL := print "https://api.github.com/repos/" (.Get "repo") -}}
{{- $githubThumbnailURL := print "https://opengraph.githubassets.com/0/" (.Get "repo") -}}
{{- $showThumbnail := .Get "showThumbnail" | default true -}}
{{- $repoColors := .Site.Data.repoColors -}}
{{- $githubData := dict -}}
{{- with try (resources.GetRemote $githubURL) -}}
{{- with .Err -}}
{{- warnf "github shortcode: failed to fetch remote resource from %q: %s" $githubURL $.Position -}}
{{- else with .Value -}}
{{- $githubData = . | transform.Unmarshal -}}
{{- else -}}
{{- warnf "github shortcode: unable to get remote resource from %q: %s" $githubURL $.Position -}}
{{- end -}}
{{- end -}}
{{- with $githubData -}}
<div class="github-card-wrapper">
<a id="{{ $id }}" target="_blank" href="{{ .html_url }}" class="cursor-pointer">
<div
class="w-full md:w-auto p-0 m-0 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl">
{{- if $showThumbnail -}}
<div class="w-full nozoom">
<img
src="{{ $githubThumbnailURL }}"
alt="GitHub Repository Thumbnail"
class="nozoom mt-0 mb-0 w-full h-full object-cover">
</div>
{{- end -}}
<div class="w-full md:w-auto pt-3 p-5">
<div class="flex items-center">
<span class="text-2xl text-neutral-800 dark:text-neutral me-2">
{{ partial "icon.html" "github" }}
</span>
<div
id="{{ $id }}-full_name"
class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral">
{{ .full_name | markdownify }}
</div>
</div>
<p id="{{ $id }}-description" class="m-0 mt-2 text-md text-neutral-800 dark:text-neutral">
{{ .description | markdownify }}
</p>
<div class="m-0 mt-2 flex items-center">
<span class="mr-1 inline-block h-3 w-3 rounded-full language-dot" data-language="{{ .language | default "default" }}"></span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ if .language }}{{ .language }}{{ else }}null{{ end }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "star" }}
</span>
<div id="{{ $id }}-stargazers" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .stargazers_count }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "fork" }}
</span>
<div id="{{ $id }}-forks" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .forks }}
</div>
</div>
</div>
</div>
{{ $fetchRepo := resources.Get "js/fetch-repo.js" }}
{{ $fetchRepo = $fetchRepo | resources.Minify | resources.Fingerprint ($.Site.Params.fingerprintAlgorithm | default "sha512") }}
<script
async
type="text/javascript"
src="{{ $fetchRepo.RelPermalink }}"
integrity="{{ $fetchRepo.Data.Integrity }}"
data-repo-url="{{ $githubURL }}"
data-repo-id="{{ $id }}"></script>
</a>
</div>
{{- else -}}
{{ warnf "github shortcode: unable to fetch %q: %s" $githubURL .Position }}
{{- end -}}

View File

@@ -0,0 +1,61 @@
{{ $id := delimit (slice "gitlab" (partial "functions/uid.html" .)) "-" }}
{{- $gitlabURL := print (default "https://gitlab.com/" (.Get "baseURL")) "api/v4/projects/" (.Get "projectID") -}}
{{- $gitLabData := dict -}}
{{- with try (resources.GetRemote $gitlabURL) -}}
{{- with .Err -}}
{{- warnf "gitlab shortcode: failed to fetch remote resource from %q: %s" $gitlabURL $.Position -}}
{{- else with .Value -}}
{{- $gitLabData = . | transform.Unmarshal -}}
{{- else -}}
{{- warnf "gitlab shortcode: unable to get remote resource from %q: %s" $gitlabURL $.Position -}}
{{- end -}}
{{- end -}}
{{- with $gitLabData -}}
<div class="gitlab-card-wrapper">
<a id="{{ $id }}" target="_blank" href="{{ .web_url }}" class="cursor-pointer">
<div
class="w-full md:w-auto pt-3 p-5 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl">
<div class="flex items-center">
<span class="text-2xl text-neutral-800 dark:text-neutral me-2">
{{ partial "icon.html" "gitlab" }}
</span>
<div
id="{{ $id }}-name_with_namespace"
class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral">
{{ .name_with_namespace | markdownify }}
</div>
</div>
<p id="{{ $id }}-description" class="m-0 mt-2 text-md text-neutral-800 dark:text-neutral">
{{ .description | markdownify }}
</p>
<div class="m-0 mt-2 flex items-center">
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "star" }}
</span>
<div id="{{ $id }}-star_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .star_count }}
</div>
<span class="text-md mr-1 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "fork" }}
</span>
<div id="{{ $id }}-forks_count" class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ .forks_count }}
</div>
</div>
</div>
{{ $fetchRepo := resources.Get "js/fetch-repo.js" }}
{{ $fetchRepo = $fetchRepo | resources.Minify | resources.Fingerprint ($.Site.Params.fingerprintAlgorithm | default "sha512") }}
<script
async
type="text/javascript"
src="{{ $fetchRepo.RelPermalink }}"
integrity="{{ $fetchRepo.Data.Integrity }}"
data-repo-url="{{ $gitlabURL }}"
data-repo-id="{{ $id }}"></script>
</a>
</div>
{{- end -}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{{- /* Avoid extra whitespace */ -}}
{{- /* https://discourse.gohugo.io/t/55399/5 */ -}}
{{- $icon := resources.Get (printf "icons/%s.svg" ($.Get 0)) -}}
{{- if $icon -}}
<span class="relative inline-block align-text-bottom icon">
{{- strings.Replace $icon.Content "\n" "" | safeHTML -}}
</span>
{{- else -}}
{{- errorf `icon shortcode: resource "%s" not found. Check the path is correct or remove the shortcode: %s` (printf "icons/%s.svg" ($.Get 0)) .Position -}}
{{- end -}}

View File

@@ -0,0 +1 @@
{{/* Nothing to see here */}}

View File

@@ -0,0 +1,13 @@
{{- $icon := .Get "icon" -}}
<div class="flex mt-2">
<span
class="rounded-full bg-primary-500 dark:bg-primary-400 text-neutral-50 dark:text-neutral-800 px-1.5 py-[1px] text-xs font-normal">
<span class="flex flex-row items-center">
{{- if $icon -}}
<span class="mr-1">{{ partial "icon" $icon }}</span>
{{- end -}}
<span> {{- .Inner | markdownify -}} </span>
</span>
</span>
</div>
{{- /* Trim EOF */ -}}

View File

@@ -0,0 +1 @@
<div class="flex flex-row flex-wrap items-center space-x-2">{{- .Inner -}}</div>

View File

@@ -0,0 +1,3 @@
<div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl">
{{ .Inner | markdownify }}
</div>

View File

@@ -0,0 +1,42 @@
{{ $limit := .Get "limit" | default 1 }}
{{ $title := .Get "title" | default (i18n "shortcode.recent_articles" | emojify) }}
{{ $parent := .Page.RelPermalink }}
{{ $cardView := .Get "cardView" }}
{{ $where := .Get "where" }}
{{ $value := .Get "value" }}
<h2 class="mt-20 text-2xl font-extrabold mb-10">{{ $title }}</h2>
{{ if $cardView | default false }}
<section class="w-full grid gap-4 sm:grid-cols-2 md:grid-cols-3">
{{ if $where }}
{{ range ( where .Site.RegularPages $where $value | first $limit ) }}
{{ if not (eq .RelPermalink $parent) }}
{{ partial "article-link/card.html" . }}
{{ end }}
{{ end }}
{{ else }}
{{ range .Site.RegularPages | first $limit }}
{{ if not (eq .RelPermalink $parent) }}
{{ partial "article-link/card.html" . }}
{{ end }}
{{ end }}
{{ end }}
</section>
{{ else }}
<section class="space-y-10 w-full mt-10 mb-10">
{{ if $where }}
{{ range ( where .Site.RegularPages $where $value | first $limit ) }}
{{ if not (eq .RelPermalink $parent) }}
{{ partial "article-link/simple.html" . }}
{{ end }}
{{ end }}
{{ else }}
{{ range .Site.RegularPages | first $limit }}
{{ if not (eq .RelPermalink $parent) }}
{{ partial "article-link/simple.html" . }}
{{ end }}
{{ end }}
{{ end }}
</section>
{{ end }}

View File

@@ -0,0 +1,3 @@
<div dir="ltr" class="text-left">
{{ .Inner }}
</div>

View File

@@ -0,0 +1,6 @@
{{ $url := .Get "url" }}
{{ with resources.GetRemote (urls.Parse $url) }}
{{ .Content | markdownify }}
{{ else }}
{{ warnf "mdimporter shortcode: unable to fetch %q: %s" $url .Position }}
{{ end }}

View File

@@ -0,0 +1 @@
<pre class="not-prose mermaid">{{ .Inner | safeHTML }}</pre>

View File

@@ -0,0 +1,3 @@
<div dir="rtl" class="text-right">
{{ .Inner }}
</div>

View File

@@ -0,0 +1,22 @@
{{ if .Get "src" }}
{{ $image := .Page.Resources.GetMatch (printf "*%s*" (.Get "src")) }}
<figure{{ with .Get "class" }} class="{{ . }}"{{ end }}>
{{- 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 -}}
width="100%"
height="auto"
style="max-width:{{ div $image.Width 2 }}px; max-height:{{ div $image.Height 2 }}px;"
/>
{{- if .Get "href" }}</a>{{ end -}}
{{- if .Get "caption" -}}
<figcaption>
{{- .Get "caption" | markdownify -}}
</figcaption>
{{- end }}
</figure>
{{ end }}

View File

@@ -0,0 +1,11 @@
<div class="flex justify-between">
<span
class="w-full py-6 mr-3 rounded-md"
{{ with .Get 0 }}style="background-color: {{ . }}"{{ end }}></span>
<span
class="w-full py-6 mr-3 rounded-md"
{{ with .Get 1 }}style="background-color: {{ . }}"{{ end }}></span>
<span
class="w-full py-6 mr-3 rounded-md"
{{ with .Get 2 }}style="background-color: {{ . }}"{{ end }}></span>
</div>

View File

@@ -0,0 +1,8 @@
{{- $label := .Get "label" -}}
{{- $icon := .Get "icon" -}}
{{- $index := .Parent.Store.Get "tab-index" | default 0 -}}
{{- $content := .InnerDeindent | strings.TrimSpace | .Page.RenderString -}}
{{- $tabs := .Parent.Store.Get "tabs" | default slice -}}
{{- .Parent.Store.Set "tabs" ($tabs | append (dict "label" $label "icon" $icon "content" $content)) -}}
{{- .Parent.Store.Set "tab-index" (add 1 $index) -}}

View File

@@ -0,0 +1,52 @@
{{- .Store.Set "tab-index" 0 -}}
{{- $noop := .Inner -}}
{{- $group := .Get "group" -}}
{{- $default := .Get "default" -}}
<div
class="tab__container w-full"
{{ with $group }}data-tab-group="{{ . }}"{{ end }}
{{ with $default }}data-default-tab="{{ . }}"{{ end }}>
<div class="tab__nav" role="tablist">
<div class="flex flex-wrap gap-1">
{{- range $nTabs, $_ := .Store.Get "tabs" -}}
{{- $isActive := false -}}
{{- if $default -}}
{{- $isActive = eq $default (index . "label") -}}
{{- else -}}
{{- $isActive = eq $nTabs 0 -}}
{{- end -}}
<button
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 {{ if $isActive -}}
tab--active
{{- end }}"
role="tab"
aria-selected="{{ cond $isActive `true` `false` }}"
data-tab-index="{{ $nTabs }}"
data-tab-label="{{ index . "label" }}">
<span class="flex items-center gap-1">
{{ with index . "icon" }}
{{ partial "icon.html" . }}
{{ end }}
{{ index . "label" }}
</span>
</button>
{{- end -}}
</div>
</div>
<div class="tab__content mt-4">
{{- range $nTabs, $_ := .Store.Get "tabs" -}}
{{- $isActive := false -}}
{{- if $default -}}
{{- $isActive = eq $default (index . "label") -}}
{{- else -}}
{{- $isActive = eq $nTabs 0 -}}
{{- end -}}
<div class="tab__panel {{ if $isActive }}tab--active{{ end }}" data-tab-index="{{ $nTabs }}">
{{ index . "content" }}
</div>
{{- end -}}
</div>
</div>

View File

@@ -0,0 +1,3 @@
<ol class="border-s-2 border-primary-500 dark:border-primary-300 list-none">
{{- .Inner -}}
</ol>

View File

@@ -0,0 +1,37 @@
{{ $icon := .Get "icon" | default "check" }}
{{ $md := .Get "md" | default false }}
{{ $header := .Get "header" }}
{{ $badge := .Get "badge" }}
{{ $subheader := .Get "subheader" }}
<li>
<div class="flex">
<div
class="bg-primary-500 dark:bg-primary-300 text-neutral-50 dark:text-neutral-700 min-w-[30px] h-8 text-2xl flex items-center justify-center rounded-full ltr:-ml-12 rtl:-mr-[79px] mt-5">
{{ partial "icon" $icon }}
</div>
<div class="block p-6 rounded-lg shadow-2xl flex-1 ms-6 mb-10 break-words">
<div class="flex justify-between">
{{ if $header }}
<h2 class="mt-0">{{ $header }}</h2>
{{ end }}
{{ if $badge }}
<h3 class="">
{{ partial "badge" $badge }}
</h3>
{{ end }}
</div>
{{ if $subheader }}
<h4 class="mt-0">
{{ $subheader }}
</h4>
{{ end }}
<div class="mb-6">
{{ if $md }}
{{- .Inner | markdownify -}}
{{ else }}
{{- .Inner -}}
{{ end }}
</div>
</div>
</div>
</li>

View File

@@ -0,0 +1,44 @@
{{- $content := split .Inner "\n" -}}
{{- $initialString := .Get "initialString" | default "" -}}
{{- $speed := .Get "speed" | default 100 -}}
{{- $lifeLike := .Get "lifeLike" | default false -}}
{{- $startDelay := .Get "startDelay" | default 0 -}}
{{- $breakLines := .Get "breakLines" | default true -}}
{{- $waitUntilVisible := .Get "waitUntilVisible" | default true -}}
{{- $loop := .Get "loop" | default false -}}
{{- $randomLines := .Get "randomLines" | default false -}}
{{- $classList := slice -}}
{{- with .Get "class" -}}
{{- $classList = $classList | append . -}}
{{- end -}}
{{- $tag := .Get "tag" | default "div" -}}
{{ $id := delimit (slice "typeit" (partial "functions/uid.html" .)) "-" }}
{{- $attrs := printf `id="%v"` $id -}}
{{- with $classList -}}
{{- $attrs = delimit $classList " " | printf `%v class="%v"` $attrs -}}
{{- end -}}
{{ printf `<%v %v>%s</%v>` $tag $attrs $initialString $tag | safeHTML }}
<script>
document.addEventListener("DOMContentLoaded", function () {
var strings = {{ $content }};
{{ if $randomLines }}
for (var i = strings.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
[strings[i], strings[j]] = [strings[j], strings[i]];
}
{{ end }}
new TypeIt("#{{ $id }}", {
strings: strings,
speed: {{ $speed }},
lifeLike: {{ $lifeLike }},
startDelay: {{ $startDelay }},
breakLines: {{ $breakLines }},
waitUntilVisible: {{ $waitUntilVisible }},
loop: {{ $loop }}
}).go();
});
</script>

View File

@@ -0,0 +1,205 @@
{{- $srcRaw := .Get "src" -}}
{{- if not $srcRaw -}}
{{- errorf "video shortcode: src is required: %s" .Position -}}
{{- end -}}
{{- $truthy := slice "true" "1" "yes" "on" -}}
{{- $srcURL := urls.Parse $srcRaw -}}
{{- $srcPath := strings.TrimPrefix "/" $srcURL.Path -}}
{{- $src := "" -}}
{{- if $srcURL.IsAbs -}}
{{- $src = $srcURL.String -}}
{{- else -}}
{{- $resource := "" -}}
{{- with $.Page.Resources.GetMatch $srcPath -}}
{{- $resource = . -}}
{{- else -}}
{{- with resources.Get $srcPath -}}
{{- $resource = . -}}
{{- end -}}
{{- end -}}
{{- if $resource -}}
{{- $src = $resource.RelPermalink -}}
{{- else if fileExists (path.Join "static" $srcPath) -}}
{{- $src = relURL $srcPath -}}
{{- end -}}
{{- end -}}
{{- if not $src -}}
{{- errorf "video shortcode: unable to resolve src %q: %s" $srcRaw .Position -}}
{{- end -}}
{{- $posterRaw := .Get "poster" -}}
{{- $poster := "" -}}
{{- if $posterRaw -}}
{{- $posterURL := urls.Parse $posterRaw -}}
{{- $posterPath := strings.TrimPrefix "/" $posterURL.Path -}}
{{- if $posterURL.IsAbs -}}
{{- $poster = $posterURL.String -}}
{{- else -}}
{{- $posterRes := "" -}}
{{- with $.Page.Resources.GetMatch $posterPath -}}
{{- $posterRes = . -}}
{{- else -}}
{{- with resources.Get $posterPath -}}
{{- $posterRes = . -}}
{{- end -}}
{{- end -}}
{{- if $posterRes -}}
{{- $poster = $posterRes.RelPermalink -}}
{{- else if fileExists (path.Join "static" $posterPath) -}}
{{- $poster = relURL $posterPath -}}
{{- else -}}
{{- warnf "video shortcode: unable to resolve poster %q: %s" $posterRaw .Position -}}
{{- end -}}
{{- end -}}
{{- else -}}
{{- if not $srcURL.IsAbs -}}
{{- $base := path.Base $srcURL.Path -}}
{{- $ext := path.Ext $base -}}
{{- $name := strings.TrimSuffix $base $ext -}}
{{- with $.Page.Resources.GetMatch (printf "%s.*" $name) -}}
{{- if eq .MediaType.MainType "image" -}}
{{- $poster = .RelPermalink -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $ratioRaw := .Get "ratio" | default "16/9" -}}
{{- $ratioTrim := replace (strings.TrimSpace $ratioRaw) " " "" -}}
{{- if not (findRE "^\\d+\\/\\d+$" $ratioTrim) -}}
{{- errorf "video shortcode: invalid ratio %q: %s" $ratioRaw .Position -}}
{{- end -}}
{{- $ratioClass := "" -}}
{{- $ratioStyle := "" -}}
{{- if eq $ratioTrim "16/9" -}}
{{- $ratioClass = "aspect-video" -}}
{{- else if eq $ratioTrim "4/3" -}}
{{- $ratioClass = "aspect-[4/3]" -}}
{{- else if eq $ratioTrim "1/1" -}}
{{- $ratioClass = "aspect-square" -}}
{{- else -}}
{{- $ratioClass = "aspect-auto" -}}
{{- $ratioStyle = printf "aspect-ratio: %s;" (replace $ratioTrim "/" " / ") -}}
{{- end -}}
{{- $preload := lower (.Get "preload" | default "metadata") -}}
{{- if not (in (slice "metadata" "auto" "none") $preload) -}}
{{- errorf "video shortcode: invalid preload %q: %s" $preload .Position -}}
{{- end -}}
{{- $fit := lower (.Get "fit" | default "contain") -}}
{{- $fitClass := "" -}}
{{- if eq $fit "contain" -}}
{{- $fitClass = "object-contain" -}}
{{- else if eq $fit "cover" -}}
{{- $fitClass = "object-cover" -}}
{{- else if eq $fit "fill" -}}
{{- $fitClass = "object-fill" -}}
{{- else -}}
{{- errorf "video shortcode: invalid fit %q: %s" $fit .Position -}}
{{- end -}}
{{- $autoplay := false -}}
{{- with .Get "autoplay" -}}
{{- $autoplay = in $truthy (lower .) -}}
{{- end -}}
{{- $loop := false -}}
{{- with .Get "loop" -}}
{{- $loop = in $truthy (lower .) -}}
{{- end -}}
{{- $muted := false -}}
{{- with .Get "muted" -}}
{{- $muted = in $truthy (lower .) -}}
{{- end -}}
{{- $controls := true -}}
{{- with .Get "controls" -}}
{{- $controls = in $truthy (lower .) -}}
{{- end -}}
{{- $playsinline := true -}}
{{- with .Get "playsinline" -}}
{{- $playsinline = in $truthy (lower .) -}}
{{- end -}}
{{- $startRaw := .Get "start" -}}
{{- $endRaw := .Get "end" -}}
{{- $start := "" -}}
{{- $end := "" -}}
{{- $startOk := false -}}
{{- $endOk := false -}}
{{- if $startRaw -}}
{{- $startTrim := strings.TrimSpace $startRaw -}}
{{- if findRE "^\\d+(\\.\\d+)?$" $startTrim -}}
{{- $start = $startTrim -}}
{{- $startOk = true -}}
{{- else -}}
{{- warnf "video shortcode: invalid start %q: %s" $startRaw .Position -}}
{{- end -}}
{{- end -}}
{{- if $endRaw -}}
{{- $endTrim := strings.TrimSpace $endRaw -}}
{{- if findRE "^\\d+(\\.\\d+)?$" $endTrim -}}
{{- $end = $endTrim -}}
{{- $endOk = true -}}
{{- else -}}
{{- warnf "video shortcode: invalid end %q: %s" $endRaw .Position -}}
{{- end -}}
{{- end -}}
{{- if and $startOk $endOk -}}
{{- if ge (float $start) (float $end) -}}
{{- warnf "video shortcode: start must be < end (start=%s, end=%s): %s" $start $end .Position -}}
{{- $start = "" -}}
{{- $end = "" -}}
{{- $startOk = false -}}
{{- $endOk = false -}}
{{- end -}}
{{- end -}}
{{- $timeValue := "" -}}
{{- if and $startOk $endOk -}}
{{- $timeValue = printf "t=%s,%s" $start $end -}}
{{- else if $startOk -}}
{{- $timeValue = printf "t=%s" $start -}}
{{- else if $endOk -}}
{{- $timeValue = printf "t=,%s" $end -}}
{{- end -}}
{{- $srcWithTime := $src -}}
{{- if $timeValue -}}
{{- if strings.Contains $src "#" -}}
{{- $srcWithTime = printf "%s&%s" $src $timeValue -}}
{{- else -}}
{{- $srcWithTime = printf "%s#%s" $src $timeValue -}}
{{- end -}}
{{- end -}}
{{- $caption := .Get "caption" -}}
<figure>
<video
class="w-full rounded-md {{ $ratioClass }} {{ $fitClass }}"
{{- with $ratioStyle }} style="{{ . }}"{{ end -}}
preload="{{ $preload }}"
{{- if $poster }} poster="{{ $poster }}"{{ end -}}
{{- if $autoplay }} autoplay{{ end -}}
{{- if $loop }} loop{{ end -}}
{{- if $muted }} muted{{ end -}}
{{- if $controls }} controls{{ end -}}
{{- if $playsinline }} playsinline{{ end -}}
>
<source src="{{ $srcWithTime }}">
<p>Your browser cannot play this video. <a href="{{ $src }}">Download video</a>.</p>
</video>
{{- with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
</figure>

View File

@@ -0,0 +1,6 @@
{{- $id := .Get "id" | default "SgXhGb-7QbU" -}}
{{- $label := .Get "id" | default "Blowfish" -}}
{{- $params := .Get "params" -}}
<lite-youtube videoid="{{ $id }}" playlabel="{{ $label }}" params="{{ $params }}"></lite-youtube>