diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e8fb3b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +md diff --git a/README.md b/README.md index ebf865d..19e1369 100644 --- a/README.md +++ b/README.md @@ -28,17 +28,28 @@ go build -o md . ``` Usage: - md [flags] + md [flags] [markdown-file] Flags: - -h, --help help for md - -v, --vim Enable vim-style navigation + -h, --help help for md + -p, --plain Render entire markdown to stdout (no pager) ``` +By default, `md` displays content in a vim-style pager. Use `--plain` to output directly to stdout. + +### Reading from stdin + +You can pipe markdown content directly to `md`: + +```bash +cat README.md | md +echo "# Hello World" | md +curl -s https://example.com/doc.md | md +``` ### Vim Navigation Keys -When using `--vim` mode, you can navigate using: +In the default pager mode, you can navigate using: - `j` / `k` - Move down/up - `gg` - Go to top diff --git a/main.go b/main.go index cdb1267..4f886d3 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "os" "path/filepath" @@ -15,49 +16,60 @@ import ( var ( plainMode bool - watchMode bool ) var rootCmd = &cobra.Command{ - Use: "md [flags] ", + Use: "md [flags] [markdown-file]", Short: "A markdown renderer and viewer for the terminal", Long: `md is a command-line tool that renders markdown files with syntax highlighting -and provides options for vim-style navigation.`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - filename := args[0] - if !filepath.IsAbs(filename) { - var err error - filename, err = filepath.Abs(filename) - if err != nil { - return fmt.Errorf("error resolving file path: %v", err) - } - } - - if _, err := os.Stat(filename); os.IsNotExist(err) { - return fmt.Errorf("file not found: %s", filename) - } +and provides options for vim-style navigation. +If no file is provided, md reads from stdin.`, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { themeManager := theme.New() mdRenderer := renderer.New(themeManager) codeHighlighter := highlighter.New(themeManager) mdViewer := viewer.New() - renderAndDisplay := func() error { - content, err := mdRenderer.RenderFile(filename, codeHighlighter) - if err != nil { - return fmt.Errorf("rendering error: %v", err) + var content string + var err error + + if len(args) == 0 || args[0] == "-" { + // Read from stdin + stdinContent, readErr := io.ReadAll(os.Stdin) + if readErr != nil { + return fmt.Errorf("error reading from stdin: %v", readErr) + } + if len(stdinContent) == 0 { + return fmt.Errorf("no input provided") + } + content, err = mdRenderer.RenderContent(stdinContent, codeHighlighter) + } else { + filename := args[0] + if !filepath.IsAbs(filename) { + filename, err = filepath.Abs(filename) + if err != nil { + return fmt.Errorf("error resolving file path: %v", err) + } } - if plainMode { - fmt.Print(content) - return nil - } else { - return mdViewer.DisplayInVimMode(content) + if _, statErr := os.Stat(filename); os.IsNotExist(statErr) { + return fmt.Errorf("file not found: %s", filename) } + + content, err = mdRenderer.RenderFile(filename, codeHighlighter) } - return renderAndDisplay() + if err != nil { + return fmt.Errorf("rendering error: %v", err) + } + + if plainMode { + fmt.Print(content) + return nil + } + return mdViewer.DisplayInVimMode(content) }, }