cat : --keep-header and --keep-title : decapitate by default
This commit is contained in:
parent
0642c15998
commit
14d124b8a6
2 changed files with 51 additions and 12 deletions
59
cat/cat.go
59
cat/cat.go
|
|
@ -13,36 +13,71 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
CMD = cmd.Cat
|
||||
SUMMARY = "cat um files together using a filelist"
|
||||
SEPARATOR = "\n---\n\n"
|
||||
CMD = cmd.Cat
|
||||
SUMMARY = "cat um files together using a filelist. removes header by default"
|
||||
HR_BLOCK = "\n---\n\n"
|
||||
DOUBLE_NEWLINE = "\n\n"
|
||||
H1 = "# "
|
||||
)
|
||||
|
||||
type options struct {
|
||||
Filelist flags.Arg
|
||||
Base flags.Flag[string]
|
||||
Help flags.Flag[bool]
|
||||
Filelist flags.Arg
|
||||
Base flags.Flag[string]
|
||||
KeepHeader flags.Flag[bool]
|
||||
KeepTitle flags.Flag[bool]
|
||||
Help flags.Flag[bool]
|
||||
}
|
||||
|
||||
func initOpts() options {
|
||||
return options{
|
||||
flags.Arg{"", "filelist. accepts from stdin if not provided"},
|
||||
flags.Flag[string]{"--base", "-b", "", "base directory prepended to files in filelist"},
|
||||
flags.Flag[bool]{"--keep-header", "-d", false, "preserve um headers in concatenated file. overrides --keep-title"},
|
||||
flags.Flag[bool]{"--keep-title", "-t", false, "preserve um titles in concatenated file"},
|
||||
flags.Flag[bool]{"--help", "-h", false, "show help"},
|
||||
}
|
||||
}
|
||||
|
||||
func cat(files []string, base string) (string, error) {
|
||||
// remove the um header:
|
||||
//
|
||||
// # title
|
||||
// : date
|
||||
// + tag
|
||||
//
|
||||
// optionally keep just the # title
|
||||
func decapitate(s string, opts options) string {
|
||||
// if there's no header at all, forget it:
|
||||
if opts.KeepHeader.IsSet() || !strings.HasPrefix(s, H1) {
|
||||
return s
|
||||
}
|
||||
// I'd rather slice and dice than mess with regex
|
||||
head, tail, ok := strings.Cut(s, DOUBLE_NEWLINE)
|
||||
if !ok {
|
||||
// head is complete if sep wasn't found:
|
||||
return head
|
||||
}
|
||||
s = tail
|
||||
if opts.KeepTitle.IsSet() {
|
||||
// we just take the first line. but when the header consists only of the title, there is no newline:
|
||||
if title, _, ok := strings.Cut(head, pipe.Newline); ok || !strings.Contains(head, pipe.Newline) {
|
||||
s = fmt.Sprintf("%s%s%s", title, DOUBLE_NEWLINE, s)
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func cat(files []string, opts options) (string, error) {
|
||||
ff := make([]string, 0, len(files))
|
||||
for _, f := range files {
|
||||
f := filepath.Join(base, f)
|
||||
dat, err := os.ReadFile(f)
|
||||
bf := filepath.Join(opts.Base.Val, f)
|
||||
dat, err := os.ReadFile(bf)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error opening target file: %w", err)
|
||||
}
|
||||
ff = append(ff, string(dat))
|
||||
s := decapitate(string(dat), opts)
|
||||
ff = append(ff, s)
|
||||
}
|
||||
return strings.Join(ff, SEPARATOR), nil
|
||||
return strings.Join(ff, HR_BLOCK), nil
|
||||
}
|
||||
|
||||
func Cat(args []string) {
|
||||
|
|
@ -52,7 +87,7 @@ func Cat(args []string) {
|
|||
if err != nil {
|
||||
log.Fatalf("um %s: %s", CMD, err)
|
||||
}
|
||||
s, err := cat(files, opts.Base.Val)
|
||||
s, err := cat(files, opts)
|
||||
if err != nil {
|
||||
log.Fatalf("um %s: %s", CMD, err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue