server/repochecker/grammalecte/markdown.go

114 lines
2.8 KiB
Go

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))
}
}
}
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
})
}