github.com/dmaizel/tests@v0.0.0-20210728163746-cae6a2d9cee8/cmd/check-markdown/parse.go (about) 1 // 2 // Copyright (c) 2019 Intel Corporation 3 // 4 // SPDX-License-Identifier: Apache-2.0 5 // 6 7 package main 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "strings" 13 14 bf "gopkg.in/russross/blackfriday.v2" 15 ) 16 17 // List of errors found by visitor. Used as the visitor cannot return an error 18 // directly. 19 var errorList []error 20 21 func (d *Doc) parse() error { 22 if !d.ShowTOC && !d.ListMode { 23 d.Logger.Info("Checking file") 24 } 25 26 err := d.parseMarkdown() 27 if err != nil { 28 return err 29 } 30 31 // mark document as having been handled 32 d.Parsed = true 33 34 return nil 35 } 36 37 // parseMarkdown parses the documents markdown. 38 func (d *Doc) parseMarkdown() error { 39 bytes, err := ioutil.ReadFile(d.Name) 40 if err != nil { 41 return err 42 } 43 44 md := bf.New(bf.WithExtensions(bf.CommonExtensions)) 45 46 root := md.Parse(bytes) 47 48 root.Walk(makeVisitor(d, d.ShowTOC)) 49 50 errorCount := len(errorList) 51 if errorCount > 0 { 52 extra := "" 53 if errorCount != 1 { 54 extra = "s" 55 } 56 57 var msg []string 58 59 for _, err := range errorList { 60 msg = append(msg, err.Error()) 61 } 62 63 return fmt.Errorf("found %d parse error%s:\n%s", 64 errorCount, 65 extra, 66 strings.Join(msg, "\n")) 67 } 68 69 return d.check() 70 } 71 72 // makeVisitor returns a function that is used to visit all document nodes. 73 // 74 // If createTOC is false, the visitor will check all nodes, but if true, the 75 // visitor will only display a table of contents for the document. 76 func makeVisitor(doc *Doc, createTOC bool) func(node *bf.Node, entering bool) bf.WalkStatus { 77 f := func(node *bf.Node, entering bool) bf.WalkStatus { 78 if !entering { 79 return bf.GoToNext 80 } 81 82 var err error 83 84 if createTOC { 85 err = doc.displayTOC(node) 86 } else { 87 err = doc.handleNode(node) 88 } 89 90 if err != nil { 91 // The visitor cannot return an error, so collect up all parser 92 // errors for dealing with later. 93 errorList = append(errorList, err) 94 } 95 96 return bf.GoToNext 97 } 98 99 return f 100 }