diff --git a/cat/cat.go b/cat/cat.go index 17d9823..06704db 100644 --- a/cat/cat.go +++ b/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) } diff --git a/tag/testdata/07.bar.md b/tag/testdata/07.bar.md new file mode 100644 index 0000000..2bf7981 --- /dev/null +++ b/tag/testdata/07.bar.md @@ -0,0 +1,4 @@ + +bar bar. + +bar bar.