summaryrefslogtreecommitdiff
path: root/internal/draft/parser.go
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'internal/draft/parser.go')
-rw-r--r--internal/draft/parser.go179
1 files changed, 0 insertions, 179 deletions
diff --git a/internal/draft/parser.go b/internal/draft/parser.go
deleted file mode 100644
index 2761c87..0000000
--- a/internal/draft/parser.go
+++ /dev/null
@@ -1,179 +0,0 @@
-package draft
-
-import (
- "regexp"
- "strings"
-
- "github.com/SayaAndy/saya-today-article-metadata-add/internal/frontmatter"
-)
-
-// layoutTokenRe matches gallery layout hints like "2x", "3x" that are
-// meaningful only to the sayauz renderer and must be dropped elsewhere.
-var layoutTokenRe = regexp.MustCompile(`^\d+x$`)
-
-type BlockKind int
-
-const (
- TextBlock BlockKind = iota
- GalleryBlock
-)
-
-// Block is one ordered piece of a section: either a run of markdown text or a
-// gallery. Exactly one of Text / Gallery is meaningful depending on Kind.
-type Block struct {
- Kind BlockKind
- Text string
- Gallery *Gallery
-}
-
-type Gallery struct {
- Timezone string
- KeyPrefix string
- Photos []Photo
-}
-
-type Photo struct {
- Key string // KeyPrefix + filename, e.g. "Sevsk/20241008-093833.jpg"
- Caption string
-}
-
-// Section is the content between two "..." separator lines, split into ordered
-// text and gallery blocks.
-type Section struct {
- Index int
- Blocks []Block
-}
-
-type Document struct {
- SourcePath string
- Codename string
- Metadata *frontmatter.Metadata
- RawContent []byte
- Body string
- Sections []Section
-}
-
-// ParseDraft parses a draft file: frontmatter metadata, the markdown body, and
-// the body split into sections (on "..." lines) of ordered text/gallery blocks.
-func ParseDraft(sourcePath, codename string, content []byte) (*Document, error) {
- metadata, body, err := frontmatter.ParseFrontmatter(content)
- if err != nil {
- return nil, err
- }
-
- doc := &Document{
- SourcePath: sourcePath,
- Codename: codename,
- Metadata: metadata,
- RawContent: content,
- Body: string(body),
- }
- doc.Sections = splitSections(doc.Body)
-
- return doc, nil
-}
-
-func splitSections(body string) []Section {
- lines := strings.Split(body, "\n")
-
- var sections []Section
- var chunk []string
-
- flush := func() {
- blocks := parseBlocks(chunk)
- chunk = nil
- if len(blocks) == 0 {
- return
- }
- sections = append(sections, Section{Index: len(sections), Blocks: blocks})
- }
-
- for _, line := range lines {
- if strings.TrimSpace(line) == "..." {
- flush()
- continue
- }
- chunk = append(chunk, line)
- }
- flush()
-
- return sections
-}
-
-func parseBlocks(lines []string) []Block {
- var blocks []Block
- var text []string
-
- flushText := func() {
- joined := strings.TrimSpace(strings.Join(text, "\n"))
- text = nil
- if joined != "" {
- blocks = append(blocks, Block{Kind: TextBlock, Text: joined})
- }
- }
-
- for i := 0; i < len(lines); i++ {
- trimmed := strings.TrimSpace(lines[i])
- if strings.HasPrefix(trimmed, "{Gallery:") {
- flushText()
- gallery, next := parseGallery(lines, i)
- if gallery != nil {
- blocks = append(blocks, Block{Kind: GalleryBlock, Gallery: gallery})
- }
- i = next
- continue
- }
- text = append(text, lines[i])
- }
- flushText()
-
- return blocks
-}
-
-// parseGallery reads a {Gallery:...} block starting at lines[start] and returns
-// the parsed gallery plus the index of the closing {/Gallery} line (or the last
-// consumed line if unterminated).
-func parseGallery(lines []string, start int) (*Gallery, int) {
- header := strings.TrimSpace(lines[start])
- header = strings.TrimPrefix(header, "{Gallery:")
- header = strings.TrimSuffix(header, "}")
- tz, keyPrefix, _ := strings.Cut(header, ":")
-
- gallery := &Gallery{Timezone: tz, KeyPrefix: keyPrefix}
-
- i := start + 1
- for ; i < len(lines); i++ {
- trimmed := strings.TrimSpace(lines[i])
- if trimmed == "{/Gallery}" {
- break
- }
- if trimmed == "" {
- continue
- }
- gallery.Photos = append(gallery.Photos, parsePhoto(keyPrefix, trimmed))
- }
-
- return gallery, i
-}
-
-func parsePhoto(keyPrefix, line string) Photo {
- parts := strings.Split(line, "|")
- for i := range parts {
- parts[i] = strings.TrimSpace(parts[i])
- }
-
- filename := parts[0]
-
- var captionParts []string
- for _, p := range parts[1:] {
- if p == "" || layoutTokenRe.MatchString(p) {
- continue
- }
- captionParts = append(captionParts, p)
- }
-
- return Photo{
- Key: keyPrefix + filename,
- Caption: strings.Join(captionParts, " "),
- }
-}