// This is all because I don't want to deal with double-escaping regex special // characters in sh. package main import ( "log" "os" "path/filepath" "regexp" ) func mapSlice[A, B any](f func(A) B, a []A) []B { b := make([]B, len(a)) for i := range b { b[i] = f(a[i]) } return b } type Replacer struct { re *regexp.Regexp replacement string } func compile(raw [2]string) Replacer { return Replacer{ re: regexp.MustCompile(raw[0]), replacement: raw[1], } } var replacers = mapSlice(compile, [][2]string{ // Chapter titles {`CHAPTER [IVX]+\.` + "\n\n" + `(.*)\.`, `# $1`}, // Section titles {`(?ms)SECTION [IVX]+\.\n\n_([^_]+)\._`, `## $1`}, // Untitled sections {`SECTION [IVX]+\.`, `
`}, // Em dashes {"--", "—"}, // Left double typographical quote {`"(\w|_\w)`, `“$1`}, // Right double typographical quote {`"`, `”`}, // Footnote superscripts {`\[(\d+)\]`, `[^$1]`}, // Left single typographical quote {`([^\pL])'(\pL|_)`, `$1‘$2`}, {`(?m)^'`, `‘`}, // Right single typographical quote {`'`, `’`}, // Block quotes {`(?m)^ +(\S)`, `> $1`}, }) func run() error { paths, err := filepath.Glob("original/*.markdown") if err != nil { return err } for _, path := range paths { b, err := os.ReadFile(path) if err != nil { return err } var edited = b for _, r := range replacers { edited = r.re.ReplaceAll(edited, []byte(r.replacement)) } outpath := filepath.Join("edited", filepath.Base(path)) err = os.WriteFile(outpath, edited, 0666) if err != nil { return err } } return nil } func main() { err := run() if err != nil { log.Fatal(err) } }