Diffstat (limited to 'internal')
| -rw-r--r-- | internal/b2/client.go | 12 | ||||
| -rw-r--r-- | internal/frontmatter/parser.go | 1 | ||||
| -rw-r--r-- | internal/lightgallery/block.go | 11 | ||||
| -rw-r--r-- | internal/lightgallery/html_renderer.go | 40 | ||||
| -rw-r--r-- | internal/lightgallery/parser.go | 35 | ||||
| -rw-r--r-- | internal/tailwind/transformer.go | 26 | ||||
| -rw-r--r-- | internal/templatemanager/templatemanager.go | 57 |
7 files changed, 47 insertions, 135 deletions
diff --git a/internal/b2/client.go b/internal/b2/client.go index 5322b84..f2b6cad 100644 --- a/internal/b2/client.go +++ b/internal/b2/client.go @@ -33,14 +33,13 @@ func NewB2Client(cfg *config.B2Config) (*B2Client, error) { type BlogPage struct { Link string - FileName string Metadata *frontmatter.Metadata } -func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) { +func (c *B2Client) Scan() ([]*BlogPage, error) { filePaths := []*BlogPage{} - iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix+prefix)) + iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix)) for iter.Next() { obj := iter.Object() @@ -70,13 +69,10 @@ func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) { return nil, fmt.Errorf("failed to parse published time metadata field: %w", err) } - linkParts := strings.Split(obj.Name(), "/") - nameParts := strings.Split(linkParts[len(linkParts)-1], ".") - fileName := strings.Join(nameParts[:len(linkParts)-1], ".") + linkParts := strings.Split(obj.Name(), ".") filePaths = append(filePaths, &BlogPage{ - Link: obj.Name(), - FileName: fileName, + Link: strings.Join(linkParts[:len(linkParts)-1], "."), Metadata: &frontmatter.Metadata{ Title: attrs.Info["title"], ShortDescription: attrs.Info["short-description"], diff --git a/internal/frontmatter/parser.go b/internal/frontmatter/parser.go index 3c00a7f..1a521c0 100644 --- a/internal/frontmatter/parser.go +++ b/internal/frontmatter/parser.go @@ -16,7 +16,6 @@ type Metadata struct { Thumbnail string `yaml:"thumbnail"` Tags []string `yaml:"tags"` Geolocation string `yaml:"geolocation"` - Timezone string `yaml:"timezone"` } func ParseFrontmatter(content []byte) (metadata *Metadata, markdown []byte, err error) { diff --git a/internal/lightgallery/block.go b/internal/lightgallery/block.go index 8eb7c9e..dade2ea 100644 --- a/internal/lightgallery/block.go +++ b/internal/lightgallery/block.go @@ -1,21 +1,16 @@ package lightgallery -import ( - "time" - - "github.com/yuin/goldmark/ast" -) +import "github.com/yuin/goldmark/ast" // LightGalleryBlock represents a light gallery block in the AST type LightGalleryBlock struct { ast.BaseBlock - Images []LightGalleryImage - Location *time.Location + Images []LightGalleryImage } type LightGalleryImage struct { URL string - Caption []byte + Caption string } var KindLightGalleryBlock = ast.NewNodeKind("LightGalleryBlock") diff --git a/internal/lightgallery/html_renderer.go b/internal/lightgallery/html_renderer.go index 850cd95..bd73eac 100644 --- a/internal/lightgallery/html_renderer.go +++ b/internal/lightgallery/html_renderer.go @@ -1,13 +1,11 @@ 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" @@ -16,18 +14,11 @@ 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) @@ -47,13 +38,13 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [ return ast.WalkContinue, nil } - galleryID := generateDivId(8) + galleryID := generateDivId(4) w.WriteString(fmt.Sprintf(` <div class="justify-content-center display-block m-2"> - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%%] ml-auto mr-auto"> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> <div id="lg-%s" class="inline-gallery-container relative ml-auto mr-auto"></div> - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%%] ml-auto mr-auto"> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> </div>`, galleryID)) var dynamicElements []string @@ -62,17 +53,7 @@ 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", @@ -86,10 +67,10 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [ thumb: "https://f003.backblazeb2.com/file/sayana-photos/thumbnails/%s.webp", subHtml: `+"`"+`<div class="flex flex-row light-gallery-captions"> - <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> + <p class="grow text-vmax1 text-left lh-0-9 font-spectral text-main-dark">%s</p> + <p class="text-vmax1 text-right lh-0-9 font-spectral text-secondary">%s</p> </div>`+"`"+` - }`, img.URL, img.URL, util.EscapeHTML(captionHTML), imageUrlWithoutExt, imageUrlWithoutExt, captionHTML, dayDate.Format("2006-01-02 15:04:05 -07:00"))) + }`, img.URL, img.URL, img.Caption, imageUrlWithoutExt, imageUrlWithoutExt, img.Caption, dayDate.Format("2006-01-02 15:04:05 -07:00"))) } w.WriteString(fmt.Sprintf(` @@ -136,6 +117,15 @@ window.addEventListener("resize", () => { return ast.WalkContinue, nil } +func escapeHTML(s string) string { + s = strings.ReplaceAll(s, "&", "&") + s = strings.ReplaceAll(s, "<", "<") + s = strings.ReplaceAll(s, ">", ">") + s = strings.ReplaceAll(s, "\"", """) + s = strings.ReplaceAll(s, "'", "'") + 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 daec797..0ce209c 100644 --- a/internal/lightgallery/parser.go +++ b/internal/lightgallery/parser.go @@ -2,9 +2,7 @@ package lightgallery import ( "bytes" - "log/slog" - "regexp" - "time" + "strings" "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/parser" @@ -24,52 +22,43 @@ 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) - 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))) + if !bytes.Equal(trimmed, []byte("{Gallery}")) { return nil, 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 + return &LightGalleryBlock{}, 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.Continue | parser.NoChildren + return parser.Close } trimmed := bytes.TrimSpace(line) - if bytes.Equal(trimmed, []byte("{Gallery}")) || bytes.Equal(trimmed, []byte("{/Gallery}")) { + if bytes.Equal(trimmed, []byte("{Gallery}")) { reader.AdvanceLine() return parser.Close } gallery := node.(*LightGalleryBlock) + lineStr := string(trimmed) - parts := bytes.SplitN(trimmed, []byte{'|'}, 2) - url := bytes.TrimSpace(parts[0]) + parts := strings.SplitN(lineStr, "|", 2) + url := strings.TrimSpace(parts[0]) + caption := "" - caption := make([]byte, 0) if len(parts) > 1 { - caption = bytes.TrimSpace(parts[1]) + caption = strings.TrimSpace(parts[1]) } gallery.Images = append(gallery.Images, LightGalleryImage{ - URL: string(url), + URL: url, Caption: caption, }) diff --git a/internal/tailwind/transformer.go b/internal/tailwind/transformer.go index 2f052b9..51a33bc 100644 --- a/internal/tailwind/transformer.go +++ b/internal/tailwind/transformer.go @@ -17,44 +17,44 @@ func (t *TailwindTransformer) Transform(node *ast.Document, reader text.Reader, switch node := n.(type) { case *ast.Heading: classes := map[int]string{ - 1: "font-patua text-[2.5vmax] font-bold text-main-dark mb-[1.2vmin] tracking-[0.04vmin]", - 2: "font-spectral text-[2vmax] font-bold text-main-dark mb-[0.8vmin] tracking-[0.04vmin]", - 3: "font-spectral text-[1.5vmax] font-medium text-main-dark mb-[0.6vmin] tracking-[0.04vmin]", - 4: "font-spectral text-[1.2vmax] font-medium text-main-medium mb-[0.4vmin] tracking-[0.04vmin]", - 5: "font-spectral text-[1vmax] font-medium text-main-medium mb-[0.4vmin] italic tracking-[0.04vmin]", - 6: "font-spectral text-[1vmax] font-medium text-secondary mb-[0.4vmin]", + 1: "font-patua text-vmax2-5 font-bold text-main-dark mb-vmin1-2 ls-vmin0-04", + 2: "font-spectral text-vmax2 font-bold text-main-dark mb-vmin0-8 ls-vmin0-04", + 3: "font-spectral text-vmax1-5 font-medium text-main-dark mb-vmin0-6 ls-vmin0-04", + 4: "font-spectral text-vmax1-2 font-medium text-main-medium mb-vmin0-4 ls-vmin0-04", + 5: "font-spectral text-vmax1 font-medium text-main-medium mb-vmin0-4 italic ls-vmin0-04", + 6: "font-spectral text-vmax1 font-medium text-secondary mb-vmin0-4", } if class, ok := classes[node.Level]; ok { node.SetAttribute([]byte("class"), []byte(class)) } case *ast.Paragraph: - node.SetAttribute([]byte("class"), []byte("text-[1vmax]/[2] font-spectral tracking-[0.04vmin] -indent-[2vmax] ml-[2vmax] mb-[1.6vmin]")) + node.SetAttribute([]byte("class"), []byte("text-vmax1 font-spectral lh-2 ls-vmin0-04 timl-vmax2 mb-vmin1-6")) case *ast.List: if node.IsOrdered() { - node.SetAttribute([]byte("class"), []byte("list-decimal list-inside space-y-[0.8vmin] mb-[1.6vmin] pl-[2vmax]")) + node.SetAttribute([]byte("class"), []byte("list-decimal list-inside space-y-vmin0-8 mb-vmin1-6 pl-vmax2")) } else { - node.SetAttribute([]byte("class"), []byte("list-disc list-inside space-y-[0.8vmin] mb-[1.6vmin] pl-[2vmax]")) + node.SetAttribute([]byte("class"), []byte("list-disc list-inside space-y-vmin0-8 mb-vmin1-6 pl-vmax2")) } case *ast.ListItem: - node.SetAttribute([]byte("class"), []byte("text-[1vmax]/[2] font-spectral tracking-[0.04vmin]")) + node.SetAttribute([]byte("class"), []byte("text-vmax1 font-spectral lh-2 ls-vmin0-04")) case *ast.Blockquote: - node.SetAttribute([]byte("class"), []byte("border-l-[0.4vmin] border-main-medium bg-background-dark p-[0.8vmin] mb-[0.8vmin] italic")) + node.SetAttribute([]byte("class"), []byte("border-l-vmin0-4 border-main-medium bg-background-dark p-vmin0-8 mb-vmin0-8 italic")) case *ast.CodeSpan: node.SetAttribute([]byte("class"), []byte("bg-background-dark")) case *ast.CodeBlock, *ast.FencedCodeBlock: - node.SetAttribute([]byte("class"), []byte("bg-background-dark p-[0.8vmin] rounded-lg overflow-x-auto mb-[1.6vmin]")) + node.SetAttribute([]byte("class"), []byte("bg-background-dark p-vmin0-8 rounded-lg overflow-x-auto mb-vmin1-6")) case *ast.Link: node.SetAttribute([]byte("class"), []byte("text-secondary hover:text-main-dark underline")) case *ast.Image: - node.SetAttribute([]byte("class"), []byte("max-w-full h-auto rounded-lg shadow-lg mb-[1.6vmin]")) + node.SetAttribute([]byte("class"), []byte("max-w-full h-auto rounded-lg shadow-lg mb-vmin1-6")) case *ast.Emphasis: switch node.Level { diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go deleted file mode 100644 index 5effcb3..0000000 --- a/internal/templatemanager/templatemanager.go +++ /dev/null @@ -1,57 +0,0 @@ -package templatemanager - -import ( - "bytes" - "fmt" - "html/template" - "path/filepath" - "strings" -) - -type TemplateManager struct { - templates map[string]templateManagerRender -} - -type templateManagerRender struct { - Main string - Tmpl *template.Template -} - -type TemplateManagerTemplates struct { - Name string - Files []string -} - -func NewTemplateManager(templates []TemplateManagerTemplates) (*TemplateManager, error) { - templateMap := make(map[string]templateManagerRender) - - for _, tmplStruct := range templates { - tmpl := template.New("").Funcs(template.FuncMap{ - "contains": strings.Contains, - }) - tmpl, err := tmpl.ParseFiles(tmplStruct.Files...) - if err != nil { - return nil, err - } - templateMap[tmplStruct.Name] = templateManagerRender{ - Main: filepath.Base(tmplStruct.Files[0]), - Tmpl: tmpl, - } - - } - - return &TemplateManager{ - templates: templateMap, - }, nil -} - -func (tm *TemplateManager) Render(name string, data interface{}) ([]byte, error) { - tmpl, exists := tm.templates[name] - if !exists { - return nil, fmt.Errorf("template %s is not found", name) - } - - var buf bytes.Buffer - err := tmpl.Tmpl.ExecuteTemplate(&buf, tmpl.Main, data) - return buf.Bytes(), err -} |