add line number support and support for text files

This commit is contained in:
2025-10-15 21:42:07 +02:00
parent ff9035f85f
commit 9c200de774
5 changed files with 66 additions and 19 deletions

View File

@@ -17,7 +17,17 @@ import (
const (
Version string = `v0.0.2`
Usage string = `epuppy [-vd] <epub file>`
Usage string = `Usage epuppy [options] <epub file>
Options:
-D --dark enable dark mode
-s --store-progress store and use previous (experimental)
-n --line-numbers add line numbers
-c --config <file> use config <file>
-d --debug enable debugging
-h --help show help message
-v --version show program version
`
)
type Config struct {
@@ -25,6 +35,7 @@ type Config struct {
Debug bool `koanf:"debug"` // -d
StoreProgress bool `koanf:"store-progress"` // -s
Darkmode bool `koanf:"dark"` // -D
LineNumbers bool `koanf:"line-numbers"` // -n
Config string `koanf:"config"` // -c
ColorDark ColorSetting `koanf:"colordark"` // comes from config file only
ColorLight ColorSetting `koanf:"colorlight"` // comes from config file only
@@ -52,6 +63,7 @@ func InitConfig(output io.Writer) (*Config, error) {
flagset.BoolP("debug", "d", false, "enable debugging")
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.StringP("config", "c", "", "read config from file")
if err := flagset.Parse(os.Args[1:]); err != nil {

View File

@@ -189,7 +189,7 @@ func (m Doc) View() string {
// update current line for later saving
// FIXME: doesn't work correctly yet
m.meta.currentline = int(float64(m.meta.lines) * m.viewport.ScrollPercent())
m.meta.currentline = int(float64(m.viewport.TotalLineCount()) * m.viewport.ScrollPercent())
var helpView string
if m.help.ShowAll {
@@ -234,13 +234,28 @@ func Pager(conf *Config, title, message string) (int, error) {
scrollto = conf.InitialProgress
}
if conf.LineNumbers {
catn := ""
for idx, line := range strings.Split(message, "\n") {
catn += fmt.Sprintf("%d: %s\n", idx, line)
}
message = catn
}
meta := Meta{
initialprogress: scrollto,
lines: len(strings.Split(message, "\r\n")),
lines: len(strings.Split(message, "\n")),
}
p := tea.NewProgram(
Doc{content: message, title: title, initialwidth: width, meta: &meta, config: conf, keys: keys},
Doc{
content: message,
title: title,
initialwidth: width,
meta: &meta,
config: conf,
keys: keys,
},
tea.WithAltScreen(), // use the full size of the terminal in its "alternate screen buffer"
tea.WithMouseCellMotion(), // turn on mouse support so we can track the mouse wheel
)

View File

@@ -2,12 +2,32 @@ package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/tlinden/epuppy/pkg/epub"
)
func View(conf *Config) (int, error) {
switch filepath.Ext(conf.Document) {
case ".epub":
return ViewEpub(conf)
default:
return ViewText(conf)
}
}
func ViewText(conf *Config) (int, error) {
data, err := os.ReadFile(conf.Document)
if err != nil {
return 0, err
}
return Pager(conf, conf.Document, string(data))
}
func ViewEpub(conf *Config) (int, error) {
book, err := epub.Open(conf.Document)
if err != nil {
return 0, err
@@ -35,8 +55,11 @@ func View(conf *Config) (int, error) {
for _, content := range book.Content {
if len(content.Body) > 0 {
buf.WriteString(conf.Colors.Chapter.
Render(fmt.Sprintf("Chapter %d: %s", chapter, content.Title)))
if content.Title != "" {
buf.WriteString(conf.Colors.Chapter.
Render(fmt.Sprintf("──────┤ %s ├──────", content.Title)))
}
buf.WriteString("\r\n\r\n")
buf.WriteString(conf.Colors.Body.Render(content.Body))
buf.WriteString("\r\n\r\n\r\n\r\n")

View File

@@ -3,9 +3,19 @@ package epub
import (
"encoding/xml"
"fmt"
"regexp"
"strings"
)
var (
cleantitle = regexp.MustCompile(`(?s)<head>.*</head>`)
cleanmarkup = regexp.MustCompile(`<[^<>]+>`)
cleanentities = regexp.MustCompile(`&.+;`)
cleancomments = regexp.MustCompile(`/*.*/`)
cleanspace = regexp.MustCompile(`^\s*`)
cleanh1 = regexp.MustCompile(`<h[1-6].*</h[1-6]>`)
)
// Content nav-point content
type Content struct {
Src string `xml:"src,attr" json:"src"`

View File

@@ -1,18 +1,5 @@
package epub
import (
"regexp"
)
var (
cleantitle = regexp.MustCompile(`(?s)<head>.*</head>`)
cleanmarkup = regexp.MustCompile(`<[^<>]+>`)
cleanentities = regexp.MustCompile(`&.+;`)
cleancomments = regexp.MustCompile(`/*.*/`)
cleanspace = regexp.MustCompile(`^\s*`)
cleanh1 = regexp.MustCompile(`<h[1-6].*</h[1-6]>`)
)
// Ncx OPS/toc.ncx
type Ncx struct {
Points []*NavPoint `xml:"navMap>navPoint" json:"points"`