package main import ( "bytes" "fmt" "strings" "srs.epita.fr/fic-server/admin/sync" lib "srs.epita.fr/fic-server/repochecker/grammalecte/lib" "srs.epita.fr/fic-server/repochecker/grammalecte/void" "github.com/yuin/goldmark" "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" "github.com/yuin/goldmark/text" "github.com/yuin/goldmark/util" "go.uber.org/multierr" ) func GrammalecteCheckMDText(str string, lang string, exceptions *sync.CheckExceptions, forbiddenStrings ...string) (errs error) { if !isRecognizedLanguage(lang) { return } if exceptions != nil { for k := range *exceptions { tmp := strings.SplitN(k, ":", 3) if len(tmp) == 3 && tmp[1] == "quote" { str = strings.Replace(str, tmp[2], "une citation a été remplacée ici", -1) } } } for _, s := range forbiddenStrings { if strings.Contains(str, s) { if !exceptions.HasException(":not-forbidden-string:" + s) { errs = multierr.Append(errs, fmt.Errorf("Forbidden string %q included in file content, don't write your flag in text", s, s)) } } } checker := &grammarChecker{ exceptions: exceptions, } voidRenderer := void.NewVoidRenderer() markdown := goldmark.New( goldmark.WithParserOptions( parser.WithASTTransformers( util.Prioritized(checker, 200), ), ), goldmark.WithRenderer( renderer.NewRenderer( renderer.WithNodeRenderers( util.Prioritized(voidRenderer, 30), ), ), ), ) var buf bytes.Buffer if err := markdown.Convert([]byte(str), &buf); err != nil { errs = multierr.Append(errs, err) } errs = multierr.Append(errs, checker.errs) errs = multierr.Append(errs, voidRenderer.Errors()) for _, err := range multierr.Errors(grammalecte("", buf.String(), 0, exceptions, &CommonOpts)) { if gerror, ok := err.(lib.GrammarError); ok { if (gerror.RuleId == "redondances_paragraphe" || gerror.RuleId == "redondances_phrase") && gerror.GetPassage() == "SubstitutDeCode" { continue } } else if serror, ok := err.(lib.SpellingError); ok { if serror.Value == "SubstitutDeCode" { continue } } errs = multierr.Append(errs, err) } return } type grammarChecker struct { exceptions *sync.CheckExceptions errs error } func (t *grammarChecker) Transform(doc *ast.Document, reader text.Reader, pc parser.Context) { ast.Walk(doc, func(node ast.Node, enter bool) (ast.WalkStatus, error) { if !enter { return ast.WalkContinue, nil } switch child := node.(type) { case *ast.Image: if len(child.Title) > 0 { t.errs = multierr.Append(t.errs, grammalecte("", string(child.Title), 0, t.exceptions, &CommonOpts)) } case *ast.Link: if len(child.Title) > 0 { t.errs = multierr.Append(t.errs, grammalecte("", string(child.Title), 0, t.exceptions, &CommonOpts)) } } return ast.WalkContinue, nil }) }