diff --git a/README.md b/README.md index f025688..c055513 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,13 @@ To disable automatic browser reload on file changes (useful for stable editing): go-grip --no-reload README.md ``` +To use a formatted version of the Markdown filename as the browser page title +(`my-guide_v2.md` becomes `My Guide V2`): + +```bash +go-grip --filename-title my-guide_v2.md +``` + To terminate the current server simply press `CTRL-C`. ## :pencil: Examples diff --git a/cmd/root.go b/cmd/root.go index 12b04ed..7013d33 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,6 +17,7 @@ var rootCmd = &cobra.Command{ port, _ := cmd.Flags().GetInt("port") boundingBox, _ := cmd.Flags().GetBool("bounding-box") noReload, _ := cmd.Flags().GetBool("no-reload") + filenameTitle, _ := cmd.Flags().GetBool("filename-title") var file string if len(args) == 1 { @@ -24,7 +25,7 @@ var rootCmd = &cobra.Command{ } parser := internal.NewParser() - server := internal.NewServer(host, port, boundingBox, browser, !noReload, parser) + server := internal.NewServer(host, port, boundingBox, browser, !noReload, filenameTitle, parser) return server.Serve(file) }, } @@ -42,4 +43,5 @@ func init() { rootCmd.Flags().IntP("port", "p", 6419, "Port to use") rootCmd.Flags().Bool("bounding-box", true, "Add bounding box to HTML") rootCmd.Flags().Bool("no-reload", false, "Disable automatic browser reload on file changes") + rootCmd.Flags().Bool("filename-title", false, "Use the Markdown filename as the HTML page title") } diff --git a/defaults/templates/layout.html b/defaults/templates/layout.html index f53e6fa..94a1cc0 100644 --- a/defaults/templates/layout.html +++ b/defaults/templates/layout.html @@ -3,7 +3,7 @@ - go-grip - markdown preview + {{ .Title }} "+defaultHTMLTitle+"") { + t.Fatalf("expected default HTML title, got %q", recorder.Body.String()) + } +} + +func TestFormatFilenameTitle(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + filename string + want string + }{ + {name: "humanizes separators", filename: "my-guide_v2.md", want: "My Guide V2"}, + {name: "uses basename", filename: "/docs/getting-started.md", want: "Getting Started"}, + {name: "preserves acronym", filename: "README.md", want: "README"}, + {name: "strips uppercase extension", filename: "release_notes.MD", want: "Release Notes"}, + {name: "collapses separators and whitespace", filename: " release---notes__v2.md", want: "Release Notes V2"}, + {name: "supports unicode", filename: "überblick-plan.md", want: "Überblick Plan"}, + {name: "falls back for empty stem", filename: ".md", want: ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if got := formatFilenameTitle(tt.filename); got != tt.want { + t.Fatalf("formatFilenameTitle(%q) = %q, want %q", tt.filename, got, tt.want) + } + }) + } +} + +func TestFilenameTitleResponses(t *testing.T) { + t.Parallel() + + tmpDir := t.TempDir() + files := []string{"my-guide_v2.md", "unsafe-