summaryrefslogtreecommitdiff
path: root/internal/lightgallery
diff refs
from:
to:
flip
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lightgallery')
-rw-r--r--internal/lightgallery/block.go11
-rw-r--r--internal/lightgallery/html_renderer.go30
-rw-r--r--internal/lightgallery/parser.go35
3 files changed, 51 insertions, 25 deletions
diff --git a/internal/lightgallery/block.go b/internal/lightgallery/block.go
index dade2ea..8eb7c9e 100644
--- a/internal/lightgallery/block.go
+++ b/internal/lightgallery/block.go
@@ -1,16 +1,21 @@
package lightgallery
-import "github.com/yuin/goldmark/ast"
+import (
+ "time"
+
+ "github.com/yuin/goldmark/ast"
+)
// LightGalleryBlock represents a light gallery block in the AST
type LightGalleryBlock struct {
ast.BaseBlock
- Images []LightGalleryImage
+ Images []LightGalleryImage
+ Location *time.Location
}
type LightGalleryImage struct {
URL string
- Caption string
+ Caption []byte
}
var KindLightGalleryBlock = ast.NewNodeKind("LightGalleryBlock")
diff --git a/internal/lightgallery/html_renderer.go b/internal/lightgallery/html_renderer.go
index e611f0b..850cd95 100644
--- a/internal/lightgallery/html_renderer.go
+++ b/internal/lightgallery/html_renderer.go
@@ -1,11 +1,13 @@
package lightgallery
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"
@@ -14,11 +16,18 @@ import (
type LightGalleryHTMLRenderer struct {
html.Config
+ md goldmark.Markdown
}
func NewLightGalleryHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
r := &LightGalleryHTMLRenderer{
Config: html.NewConfig(),
+ md: goldmark.New(
+ goldmark.WithRendererOptions(
+ html.WithHardWraps(),
+ html.WithXHTML(),
+ ),
+ ),
}
for _, opt := range opts {
opt.SetHTMLOption(&r.Config)
@@ -53,7 +62,17 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [
imageUrlWithoutExt := strings.Join(imageUrlSegments[:len(imageUrlSegments)-1], ".")
imageNameParts := strings.Split(imageUrlWithoutExt, "-")
+ 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("<p>"))
+ captionHTML = bytes.TrimSuffix(captionHTML, []byte("</p>\n"))
+ captionHTML = bytes.TrimSuffix(captionHTML, []byte("</p>"))
+ }
+
dayDate, _ := time.Parse("20060102 150405", imageNameParts[len(imageNameParts)-2]+" "+imageNameParts[len(imageNameParts)-1])
+ dayDate = dayDate.In(gallery.Location)
dynamicElements = append(dynamicElements, fmt.Sprintf(`{
src:
"https://f003.backblazeb2.com/file/sayana-photos/full/%s",
@@ -70,7 +89,7 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [
<p class="grow !text-[1vmax]/[0.9] text-left font-spectral text-main-dark">%s</p>
<p class="!text-[1vmax]/[0.9] text-right font-spectral text-secondary">%s</p>
</div>`+"`"+`
- }`, img.URL, img.URL, img.Caption, imageUrlWithoutExt, imageUrlWithoutExt, img.Caption, dayDate.Format("2006-01-02 15:04:05 -07:00")))
+ }`, img.URL, img.URL, util.EscapeHTML(captionHTML), imageUrlWithoutExt, imageUrlWithoutExt, captionHTML, dayDate.Format("2006-01-02 15:04:05 -07:00")))
}
w.WriteString(fmt.Sprintf(`
@@ -117,15 +136,6 @@ window.addEventListener("resize", () => {
return ast.WalkContinue, nil
}
-func escapeHTML(s string) string {
- s = strings.ReplaceAll(s, "&", "&amp;")
- s = strings.ReplaceAll(s, "<", "&lt;")
- s = strings.ReplaceAll(s, ">", "&gt;")
- s = strings.ReplaceAll(s, "\"", "&quot;")
- s = strings.ReplaceAll(s, "'", "&#39;")
- return s
-}
-
func generateDivId(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyz"
seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) // Seed with current time
diff --git a/internal/lightgallery/parser.go b/internal/lightgallery/parser.go
index 0ce209c..daec797 100644
--- a/internal/lightgallery/parser.go
+++ b/internal/lightgallery/parser.go
@@ -2,7 +2,9 @@ package lightgallery
import (
"bytes"
- "strings"
+ "log/slog"
+ "regexp"
+ "time"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
@@ -22,43 +24,52 @@ func (p *LightGalleryParser) Trigger() []byte {
func (p *LightGalleryParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State) {
line, _ := reader.PeekLine()
- if !bytes.HasPrefix(line, []byte("{Gallery}")) {
+ if !bytes.HasPrefix(line, []byte("{Gallery:")) {
return nil, parser.NoChildren
}
+ r := regexp.MustCompile(`^\{Gallery:([A-Za-z0-9\+\-/]+)\}$`)
+
trimmed := bytes.TrimSpace(line)
- if !bytes.Equal(trimmed, []byte("{Gallery}")) {
+ parts := r.FindSubmatch(trimmed)
+ if len(parts) < 2 {
+ slog.Warn("invalid gallery header format", slog.String("line", string(trimmed)), slog.Int("submatch_count", len(parts)))
return nil, parser.NoChildren
}
- return &LightGalleryBlock{}, parser.NoChildren
+ loc, err := time.LoadLocation(string(parts[1]))
+ if err != nil {
+ slog.Warn("invalid location specified for a gallery", slog.String("error", err.Error()), slog.String("line", string(trimmed)), slog.String("location", string(parts[1])))
+ return nil, parser.NoChildren
+ }
+
+ return &LightGalleryBlock{Location: loc}, parser.NoChildren
}
func (p *LightGalleryParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
line, segment := reader.PeekLine()
if len(line) == 0 || segment.Len() == 0 {
- return parser.Close
+ return parser.Continue | parser.NoChildren
}
trimmed := bytes.TrimSpace(line)
- if bytes.Equal(trimmed, []byte("{Gallery}")) {
+ if bytes.Equal(trimmed, []byte("{Gallery}")) || bytes.Equal(trimmed, []byte("{/Gallery}")) {
reader.AdvanceLine()
return parser.Close
}
gallery := node.(*LightGalleryBlock)
- lineStr := string(trimmed)
- parts := strings.SplitN(lineStr, "|", 2)
- url := strings.TrimSpace(parts[0])
- caption := ""
+ parts := bytes.SplitN(trimmed, []byte{'|'}, 2)
+ url := bytes.TrimSpace(parts[0])
+ caption := make([]byte, 0)
if len(parts) > 1 {
- caption = strings.TrimSpace(parts[1])
+ caption = bytes.TrimSpace(parts[1])
}
gallery.Images = append(gallery.Images, LightGalleryImage{
- URL: url,
+ URL: string(url),
Caption: caption,
})