mirror of
https://github.com/maaslalani/slides.git
synced 2026-01-09 14:28:05 -05:00
committed by
Maas Lalani
parent
45ea575822
commit
74d6d19a30
@@ -1,10 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
"time"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
@@ -24,14 +22,8 @@ var root = &cobra.Command{
|
||||
fileName = args[0]
|
||||
}
|
||||
|
||||
user, err := user.Current()
|
||||
if err != nil {
|
||||
return errors.New("could not get current user")
|
||||
}
|
||||
|
||||
presentation := model.Model{
|
||||
Page: 0,
|
||||
Author: user.Name,
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
FileName: fileName,
|
||||
}
|
||||
|
||||
@@ -3,22 +3,28 @@
|
||||
package meta
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
const defaultTheme = "default"
|
||||
|
||||
// Temporary structure to differentiate values not present in the YAML header
|
||||
// from values set to empty strings in the YAML header. We replace values not
|
||||
// set by defaults values when parsing a header.
|
||||
type parsedMeta struct {
|
||||
Theme *string `yaml:"theme"`
|
||||
Theme *string `yaml:"theme"`
|
||||
Author *string `yaml:"author"`
|
||||
Date *string `yaml:"date"`
|
||||
Numbering *string `yaml:"numbering"`
|
||||
}
|
||||
|
||||
// Meta contains all of the data to be parsed
|
||||
// out of a markdown file's header section
|
||||
type Meta struct {
|
||||
Theme string
|
||||
Theme string
|
||||
Author string
|
||||
Date string
|
||||
Numbering string
|
||||
}
|
||||
|
||||
// New creates a new instance of the
|
||||
@@ -33,7 +39,12 @@ func New() *Meta {
|
||||
// If no front matter is provided, it will fallback to the default theme and
|
||||
// return false to acknowledge that there is no front matter in this slide
|
||||
func (m *Meta) Parse(header string) (*Meta, bool) {
|
||||
fallback := &Meta{Theme: defaultTheme}
|
||||
fallback := &Meta{
|
||||
Theme: defaultTheme(),
|
||||
Author: defaultAuthor(),
|
||||
Date: defaultDate(),
|
||||
Numbering: defaultNumbering(),
|
||||
}
|
||||
|
||||
var tmp parsedMeta
|
||||
err := yaml.Unmarshal([]byte(header), &tmp)
|
||||
@@ -47,5 +58,44 @@ func (m *Meta) Parse(header string) (*Meta, bool) {
|
||||
m.Theme = fallback.Theme
|
||||
}
|
||||
|
||||
if tmp.Author != nil {
|
||||
m.Author = *tmp.Author
|
||||
} else {
|
||||
m.Author = fallback.Author
|
||||
}
|
||||
|
||||
if tmp.Date != nil {
|
||||
m.Date = *tmp.Date
|
||||
} else {
|
||||
m.Date = fallback.Date
|
||||
}
|
||||
|
||||
if tmp.Numbering != nil {
|
||||
m.Numbering = *tmp.Numbering
|
||||
} else {
|
||||
m.Numbering = fallback.Numbering
|
||||
}
|
||||
|
||||
return m, true
|
||||
}
|
||||
|
||||
func defaultTheme() string {
|
||||
return "default"
|
||||
}
|
||||
|
||||
func defaultAuthor() string {
|
||||
user, err := user.Current()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return user.Name
|
||||
}
|
||||
|
||||
func defaultDate() string {
|
||||
return "2006-01-02"
|
||||
}
|
||||
|
||||
func defaultNumbering() string {
|
||||
return "Slide %d / %d"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package meta_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/user"
|
||||
"testing"
|
||||
|
||||
"github.com/maaslalani/slides/internal/meta"
|
||||
@@ -9,6 +10,9 @@ import (
|
||||
)
|
||||
|
||||
func TestMeta_ParseHeader(t *testing.T) {
|
||||
user, _ := user.Current()
|
||||
date := "2006-01-02"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
slideshow string
|
||||
@@ -18,21 +22,90 @@ func TestMeta_ParseHeader(t *testing.T) {
|
||||
name: "Parse theme from header",
|
||||
slideshow: fmt.Sprintf("---\ntheme: %q\n", "dark"),
|
||||
want: &meta.Meta{
|
||||
Theme: "dark",
|
||||
Theme: "dark",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fallback to default if no theme provided",
|
||||
slideshow: "\n# Header Slide\n > Subtitle\n",
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Parse author from header",
|
||||
slideshow: fmt.Sprintf("---\nauthor: %q\n", "gopher"),
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Author: "gopher",
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fallback to default if no author provided",
|
||||
slideshow: "\n# Header Slide\n > Subtitle\n",
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Parse date from header",
|
||||
slideshow: fmt.Sprintf("---\ndate: %q\n", "31/01/1970"),
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: "31/01/1970",
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fallback to default if no date provided",
|
||||
slideshow: "\n# Header Slide\n > Subtitle\n",
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Parse numbering from header",
|
||||
slideshow: fmt.Sprintf("---\nnumbering: %q\n", "%d of %d"),
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "%d of %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fallback to default if no numebring provided",
|
||||
slideshow: "\n# Header Slide\n > Subtitle\n",
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fallback if first slide is valid yaml",
|
||||
slideshow: "---\n# Header Slide---\nContent\n",
|
||||
want: &meta.Meta{
|
||||
Theme: "default",
|
||||
Theme: "default",
|
||||
Author: user.Name,
|
||||
Date: date,
|
||||
Numbering: "Slide %d / %d",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -67,6 +140,9 @@ func ExampleMeta_Parse() {
|
||||
header := `
|
||||
---
|
||||
theme: "dark"
|
||||
author: "Gopher"
|
||||
date: "Apr. 4, 2021"
|
||||
numbering: "%d"
|
||||
---
|
||||
`
|
||||
// Parse the header from the markdown
|
||||
@@ -76,4 +152,7 @@ theme: "dark"
|
||||
// Print the return theme
|
||||
// meta
|
||||
fmt.Println(m.Theme)
|
||||
fmt.Println(m.Author)
|
||||
fmt.Println(m.Date)
|
||||
fmt.Println(m.Numbering)
|
||||
}
|
||||
|
||||
@@ -25,13 +25,14 @@ const (
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
Slides []string
|
||||
Page int
|
||||
Author string
|
||||
Date string
|
||||
Theme glamour.TermRendererOption
|
||||
FileName string
|
||||
viewport viewport.Model
|
||||
Slides []string
|
||||
Page int
|
||||
Author string
|
||||
Date string
|
||||
Theme glamour.TermRendererOption
|
||||
Numbering string
|
||||
FileName string
|
||||
viewport viewport.Model
|
||||
// VirtualText is used for additional information that is not part of the
|
||||
// original slides, it will be displayed on a slide and reset on page change
|
||||
VirtualText string
|
||||
@@ -80,6 +81,9 @@ func (m *Model) Load() error {
|
||||
}
|
||||
|
||||
m.Slides = slides
|
||||
m.Author = metaData.Author
|
||||
m.Date = time.Now().Format(metaData.Date)
|
||||
m.Numbering = metaData.Numbering
|
||||
if m.Theme == nil {
|
||||
m.Theme = styles.SelectTheme(metaData.Theme)
|
||||
}
|
||||
@@ -145,11 +149,22 @@ func (m Model) View() string {
|
||||
slide = styles.Slide.Render(slide)
|
||||
|
||||
left := styles.Author.Render(m.Author) + styles.Date.Render(m.Date)
|
||||
right := styles.Page.Render(fmt.Sprintf("Slide %d / %d", m.Page+1, len(m.Slides)))
|
||||
right := styles.Page.Render(m.numbering())
|
||||
status := styles.Status.Render(styles.JoinHorizontal(left, right, m.viewport.Width))
|
||||
return styles.JoinVertical(slide, status, m.viewport.Height)
|
||||
}
|
||||
|
||||
func (m *Model) numbering() string {
|
||||
switch strings.Count(m.Numbering, "%d") {
|
||||
case 2:
|
||||
return fmt.Sprintf(m.Numbering, m.Page+1, len(m.Slides))
|
||||
case 1:
|
||||
return fmt.Sprintf(m.Numbering, m.Page+1)
|
||||
default:
|
||||
return m.Numbering
|
||||
}
|
||||
}
|
||||
|
||||
func readFile(path string) (string, error) {
|
||||
s, err := os.Stat(path)
|
||||
if err != nil {
|
||||
@@ -164,7 +179,6 @@ func readFile(path string) (string, error) {
|
||||
}
|
||||
content := string(b)
|
||||
|
||||
|
||||
// Pre-process slides if the file is executable to avoid
|
||||
// unintentional code execution when presenting slides
|
||||
if file.IsExecutable(s) {
|
||||
|
||||
Reference in New Issue
Block a user