diff --git a/cmd/markdown/main.go b/cmd/markdown/main.go index 22525ae..34d8e3c 100644 --- a/cmd/markdown/main.go +++ b/cmd/markdown/main.go @@ -5,13 +5,11 @@ import ( "flag" "fmt" "github.com/knieriem/markdown" - "io/ioutil" + "log" "os" ) func main() { - var b []byte - flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [FILE]\n", os.Args[0]) flag.PrintDefaults() @@ -21,10 +19,14 @@ func main() { optDlists := flag.Bool("dlists", false, "support definitions lists") flag.Parse() + r := os.Stdin if flag.NArg() > 0 { - b, _ = ioutil.ReadFile(flag.Arg(0)) - } else { - b, _ = ioutil.ReadAll(os.Stdin) + f, err := os.Open(flag.Arg(0)) + if err != nil { + log.Fatal(err) + } + defer f.Close() + r = f } e := markdown.Extensions{ @@ -36,7 +38,7 @@ func main() { startPProf() defer stopPProf() - doc := markdown.Parse(string(b), e) + doc := markdown.Parse(r, e) w := bufio.NewWriter(os.Stdout) doc.WriteHtml(w) w.Flush() diff --git a/doc.go b/doc.go index 79def4b..4a76f33 100644 --- a/doc.go +++ b/doc.go @@ -3,17 +3,16 @@ A translation of peg-markdown [1] into Go. Usage example: + package main + import ( - md "markdown" + md "github.com/knieriem/markdown" "os" - "io/ioutil" "bufio" ) func main() { - b, _ := ioutil.ReadAll(os.Stdin) - - doc := md.Parse(string(b), md.Extensions{Smart: true}) + doc := md.Parse(os.Stdin, md.Extensions{Smart: true}) w := bufio.NewWriter(os.Stdout) doc.WriteHtml(w) diff --git a/markdown.go b/markdown.go index ac7132c..0a29b4d 100644 --- a/markdown.go +++ b/markdown.go @@ -21,6 +21,7 @@ package markdown import ( "bytes" + "io" "log" "strings" ) @@ -35,7 +36,7 @@ type Extensions struct { } // Parse converts a Markdown document into a tree for later output processing. -func Parse(text string, ext Extensions) *Doc { +func Parse(r io.Reader, ext Extensions) *Doc { d := new(Doc) d.extension = ext @@ -43,7 +44,7 @@ func Parse(text string, ext Extensions) *Doc { d.parser.Doc = d d.parser.Init() - s := preformat(text) + s := preformat(r) d.parseRule(ruleReferences, s) if ext.Notes { @@ -109,31 +110,39 @@ const ( /* preformat - allocate and copy text buffer while * performing tab expansion. */ -func preformat(text string) (s string) { +func preformat(r io.Reader) (s string) { charstotab := TABSTOP - i0 := 0 + buf := make([]byte, 32768) - b := bytes.NewBuffer(make([]byte, 0, len(text)+256)) - for i, _ := range text { - switch text[i] { - case '\t': - b.WriteString(text[i0:i]) - for ; charstotab > 0; charstotab-- { - b.WriteByte(' ') + b := bytes.NewBuffer(make([]byte, 0, 32768)) + for { + n, err := r.Read(buf) + if err != nil { + break + } + i0 := 0 + for i := range buf[:n] { + switch buf[i] { + case '\t': + b.Write(buf[i0:i]) + for ; charstotab > 0; charstotab-- { + b.WriteByte(' ') + } + i0 = i + 1 + case '\n': + b.Write(buf[i0 : i+1]) + i0 = i + 1 + charstotab = TABSTOP + default: + charstotab-- + } + if charstotab == 0 { + charstotab = TABSTOP } - i0 = i + 1 - case '\n': - b.WriteString(text[i0 : i+1]) - i0 = i + 1 - charstotab = TABSTOP - default: - charstotab-- - } - if charstotab == 0 { - charstotab = TABSTOP } + b.Write(buf[i0:n]) } - b.WriteString(text[i0:]) + b.WriteString("\n\n") return b.String() }