From 44fe2478478225450becb77ad5d273462c9b400a Mon Sep 17 00:00:00 2001
From: SayaAndy
Date: Thu, 16 Oct 2025 12:23:00 +0700
Subject: feat: implement new prototype gallery
---
internal/glightbox/html_renderer.go | 134 ++++++++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+)
create mode 100644 internal/glightbox/html_renderer.go
(limited to 'internal/glightbox/html_renderer.go')
diff --git a/internal/glightbox/html_renderer.go b/internal/glightbox/html_renderer.go
new file mode 100644
index 0000000..3b6a533
--- /dev/null
+++ b/internal/glightbox/html_renderer.go
@@ -0,0 +1,134 @@
+package glightbox
+
+import (
+ "bytes"
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+
+ "github.com/yuin/goldmark"
+ "github.com/yuin/goldmark/ast"
+ "github.com/yuin/goldmark/renderer"
+ "github.com/yuin/goldmark/renderer/html"
+ "github.com/yuin/goldmark/util"
+)
+
+type GLightboxHTMLRenderer struct {
+ html.Config
+ md goldmark.Markdown
+}
+
+func NewGLightboxHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
+ r := &GLightboxHTMLRenderer{
+ Config: html.NewConfig(),
+ md: goldmark.New(
+ goldmark.WithRendererOptions(
+ html.WithHardWraps(),
+ html.WithXHTML(),
+ ),
+ ),
+ }
+ for _, opt := range opts {
+ opt.SetHTMLOption(&r.Config)
+ }
+ return r
+}
+
+func (r *GLightboxHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
+ reg.Register(KindGLightboxBlock, r.renderGLightbox)
+}
+
+func (r *GLightboxHTMLRenderer) renderGLightbox(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
+ if entering {
+ gallery := n.(*GLightboxBlock)
+
+ if len(gallery.Images) == 0 {
+ return ast.WalkContinue, nil
+ }
+
+ galleryID := generateDivId(8)
+
+ var elements []string
+ for i, img := range gallery.Images {
+ imageUrlSegments := strings.Split(img.URL, ".")
+ imageUrlWithoutExt := strings.Join(imageUrlSegments[:len(imageUrlSegments)-1], ".")
+ imageUrlParts := strings.Split(imageUrlWithoutExt, "/")
+ imageNameParts := strings.Split(imageUrlParts[len(imageUrlParts)-1], "-")
+
+ var captionBuf bytes.Buffer
+ captionHTML := img.Caption
+ if err := r.md.Convert(img.Caption, &captionBuf); err == nil {
+ captionHTML = captionBuf.Bytes()
+ captionHTML = bytes.TrimPrefix(captionHTML, []byte(""))
+ captionHTML = bytes.TrimSuffix(captionHTML, []byte("
\n"))
+ captionHTML = bytes.TrimSuffix(captionHTML, []byte("
"))
+ }
+
+ dayDate, _ := time.Parse("20060102 150405", imageNameParts[len(imageNameParts)-2]+" "+imageNameParts[len(imageNameParts)-1])
+ dayDate = dayDate.In(gallery.Location)
+
+ glightboxDescId := ""
+ if len(captionHTML) != 0 {
+ glightboxDescId = fmt.Sprintf("glightbox-desc-%s-%d", galleryID, i)
+ }
+
+ dataDescriptionAttribute := ""
+ if glightboxDescId != "" {
+ dataDescriptionAttribute = fmt.Sprintf("data-description=\".%s\"", glightboxDescId)
+ }
+
+ elements = append(elements, fmt.Sprintf(`
+
+
+ `, img.URL, galleryID, galleryID, galleryID, dayDate.Format("2006-01-02 15:04:05 -07:00"), dataDescriptionAttribute, imageUrlWithoutExt))
+
+ if glightboxDescId != "" {
+ elements = append(elements, fmt.Sprintf(`
+ `, glightboxDescId, captionHTML))
+ }
+ }
+
+ w.WriteString(fmt.Sprintf(`
+`, galleryID, galleryID, strings.Join(elements, "\n")))
+
+ w.WriteString(fmt.Sprintf(`
+`, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID))
+ }
+
+ return ast.WalkContinue, nil
+}
+
+func generateDivId(length int) string {
+ const charset = "abcdefghijklmnopqrstuvwxyz"
+ seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) // Seed with current time
+ b := make([]byte, length)
+ for i := range b {
+ b[i] = charset[seededRand.Intn(len(charset))]
+ }
+ return string(b)
+}
--
cgit v1.3.1+13