mirror of
https://codeberg.org/scip/epuppy.git
synced 2025-12-16 20:11:00 +01:00
Add dump feature, enhance code quality (#1)
This commit is contained in:
@@ -21,13 +21,13 @@ const (
|
||||
|
||||
Options:
|
||||
-D --dark enable dark mode
|
||||
-s --store-progress store and use previous (experimental)
|
||||
-s --store-progress remember reading position
|
||||
-n --line-numbers add line numbers
|
||||
-c --config <file> use config <file>
|
||||
-t --txt dump readable content to STDOUT
|
||||
-d --debug enable debugging
|
||||
-h --help show help message
|
||||
-v --version show program version
|
||||
`
|
||||
-v --version show program version`
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@@ -36,6 +36,7 @@ type Config struct {
|
||||
StoreProgress bool `koanf:"store-progress"` // -s
|
||||
Darkmode bool `koanf:"dark"` // -D
|
||||
LineNumbers bool `koanf:"line-numbers"` // -n
|
||||
Dump bool `koanf:"txt"` // -t
|
||||
Config string `koanf:"config"` // -c
|
||||
ColorDark ColorSetting `koanf:"colordark"` // comes from config file only
|
||||
ColorLight ColorSetting `koanf:"colorlight"` // comes from config file only
|
||||
@@ -64,6 +65,7 @@ func InitConfig(output io.Writer) (*Config, error) {
|
||||
flagset.BoolP("dark", "D", false, "enable dark mode")
|
||||
flagset.BoolP("store-progress", "s", false, "store reading progress")
|
||||
flagset.BoolP("line-numbers", "n", false, "add line numbers")
|
||||
flagset.BoolP("txt", "t", false, "dump readable content to STDOUT")
|
||||
flagset.StringP("config", "c", "", "read config from file")
|
||||
|
||||
if err := flagset.Parse(os.Args[1:]); err != nil {
|
||||
|
||||
34
cmd/pager.go
34
cmd/pager.go
@@ -43,7 +43,6 @@ type Meta struct {
|
||||
lines int
|
||||
currentline int
|
||||
initialprogress int
|
||||
document string
|
||||
}
|
||||
|
||||
type keyMap struct {
|
||||
@@ -152,9 +151,7 @@ func (m Doc) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.viewport = viewport.New(msg.Width, msg.Height-verticalMarginHeight)
|
||||
m.viewport.YPosition = headerHeight
|
||||
|
||||
m.viewport.SetContent(wordwrap.String(m.content, m.initialwidth))
|
||||
m.viewport.ScrollDown(m.meta.initialprogress)
|
||||
|
||||
m.Rewrap()
|
||||
m.ready = true
|
||||
} else {
|
||||
m.viewport.Width = msg.Width
|
||||
@@ -171,15 +168,35 @@ func (m Doc) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
// re-calculate word wrapping, also add left margin
|
||||
// re-calculate word wrapping, add left margin, recalculate line count
|
||||
func (m *Doc) Rewrap() {
|
||||
var content string
|
||||
|
||||
// width has changed, either because the terminal size changed or
|
||||
// because the user added some margin
|
||||
if m.lastwidth != m.viewport.Width || m.marginMod {
|
||||
m.viewport.SetContent(wordwrap.String(m.content, m.viewport.Width-(m.margin*2)))
|
||||
content = wordwrap.String(m.content, m.viewport.Width-(m.margin*2))
|
||||
m.lastwidth = m.viewport.Width
|
||||
m.marginMod = false
|
||||
|
||||
m.viewport.Style = viewstyle.MarginLeft(m.margin)
|
||||
}
|
||||
|
||||
// bootstrapping, initialize with default width
|
||||
if !m.ready {
|
||||
content = wordwrap.String(m.content, m.initialwidth)
|
||||
}
|
||||
|
||||
// wrapping has changed, update viewport and line count
|
||||
if content != "" {
|
||||
m.viewport.SetContent(content)
|
||||
m.meta.lines = len(strings.Split(content, "\n"))
|
||||
}
|
||||
|
||||
// during bootstrapping: jump to last remembered position, if any
|
||||
if !m.ready {
|
||||
m.viewport.ScrollDown(m.meta.initialprogress)
|
||||
}
|
||||
}
|
||||
|
||||
func (m Doc) View() string {
|
||||
@@ -188,8 +205,7 @@ func (m Doc) View() string {
|
||||
}
|
||||
|
||||
// update current line for later saving
|
||||
// FIXME: doesn't work correctly yet
|
||||
m.meta.currentline = int(float64(m.viewport.TotalLineCount()) * m.viewport.ScrollPercent())
|
||||
m.meta.currentline = int(float64(m.meta.lines) * m.viewport.ScrollPercent())
|
||||
|
||||
var helpView string
|
||||
if m.help.ShowAll {
|
||||
@@ -261,7 +277,7 @@ func Pager(conf *Config, title, message string) (int, error) {
|
||||
)
|
||||
|
||||
if _, err := p.Run(); err != nil {
|
||||
return 0, fmt.Errorf("could not run pager:", err)
|
||||
return 0, fmt.Errorf("could not run pager: %w", err)
|
||||
}
|
||||
|
||||
if conf.Debug {
|
||||
|
||||
25
cmd/store.go
25
cmd/store.go
@@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@@ -21,20 +22,28 @@ func StoreProgress(conf *Config, progress int) error {
|
||||
cfgpath := conf.GetConfigDir()
|
||||
|
||||
if err := Mkdir(cfgpath); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to mkdir config path %s: %w", cfgpath, err)
|
||||
}
|
||||
|
||||
filename := filepath.Join(cfgpath, Slug(conf.Document))
|
||||
|
||||
fd, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to open state file %s: %w", filename, err)
|
||||
}
|
||||
defer fd.Close()
|
||||
defer func() {
|
||||
if err := fd.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = fd.WriteString(fmt.Sprintf("%d\n", progress))
|
||||
if err := fd.Truncate(0); err != nil {
|
||||
return fmt.Errorf("failed to truncate state file %s: %w", filename, err)
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(fd, "%d\n", progress)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to write to state file %s: %w", filename, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -49,7 +58,11 @@ func GetProgress(conf *Config) (int64, error) {
|
||||
if err != nil {
|
||||
return 0, nil // ignore errors and return no progress
|
||||
}
|
||||
defer fd.Close()
|
||||
defer func() {
|
||||
if err := fd.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
scanner := bufio.NewScanner(fd)
|
||||
var line string
|
||||
|
||||
26
cmd/view.go
26
cmd/view.go
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -24,6 +25,10 @@ func ViewText(conf *Config) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if conf.Dump {
|
||||
return fmt.Println(string(data))
|
||||
}
|
||||
|
||||
return Pager(conf, conf.Document, string(data))
|
||||
}
|
||||
|
||||
@@ -32,7 +37,12 @@ func ViewEpub(conf *Config) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer book.Close()
|
||||
|
||||
defer func() {
|
||||
if err := book.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
buf := strings.Builder{}
|
||||
head := strings.Builder{}
|
||||
@@ -61,10 +71,22 @@ func ViewEpub(conf *Config) (int, error) {
|
||||
|
||||
}
|
||||
buf.WriteString("\r\n\r\n")
|
||||
buf.WriteString(conf.Colors.Body.Render(content.Body))
|
||||
|
||||
if conf.Dump {
|
||||
// avoid excess whitespaces when printing to stdout
|
||||
buf.WriteString(content.Body)
|
||||
} else {
|
||||
buf.WriteString(conf.Colors.Body.Render(content.Body))
|
||||
}
|
||||
|
||||
buf.WriteString("\r\n\r\n\r\n\r\n")
|
||||
chapter++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if conf.Dump {
|
||||
return fmt.Println(buf.String())
|
||||
}
|
||||
|
||||
return Pager(conf, head.String(), buf.String())
|
||||
|
||||
Reference in New Issue
Block a user