repochecker/grammalecte: New plugin to check french grammar
This commit is contained in:
parent
721908ee18
commit
edde9f885d
6 changed files with 431 additions and 5 deletions
202
repochecker/grammalecte/grammalecte.go
Normal file
202
repochecker/grammalecte/grammalecte.go
Normal file
|
@ -0,0 +1,202 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type GrammalecteOptions struct {
|
||||
Typographie bool `json:"basic"`
|
||||
SignesTypographiques bool `json:"typo"`
|
||||
ApostropheTypographiques bool `json:"apos"`
|
||||
EcritureEpicene bool `json:"eepi"`
|
||||
EspaceSurnumeraires bool `json:"tab"`
|
||||
EspaceInsecables bool `json:"nbsp"`
|
||||
Majuscules bool `json:"maj"`
|
||||
MajusculesPourMinisteres bool `json:"minis"`
|
||||
Virgules bool `json:"virg"`
|
||||
PonctuationFinale bool `json:"poncfin"`
|
||||
TraitsDUnionEtSoudures bool `json:"tu"`
|
||||
Nombres bool `json:"num"`
|
||||
UnitesDeMesure bool `json:"unit"`
|
||||
NormesFrancaises bool `json:"nf"`
|
||||
LigaturesTypographiques bool `json:"liga"`
|
||||
ApostropheManquate bool `json:"mapos"`
|
||||
Chimie bool `json:"chim"`
|
||||
ErreurDeNumerisation bool `json:"ocr"`
|
||||
NomsEtAdjectifs bool `json:"gramm"`
|
||||
FauxAmis bool `json:"conf"`
|
||||
Locutions bool `json:"loc"`
|
||||
Accords bool `json:"gn"`
|
||||
Verbes bool `json:"verbs"`
|
||||
Conjugaisons bool `json:"conj"`
|
||||
Infinitif bool `json:"infi"`
|
||||
Imperatif bool `json:"imp"`
|
||||
Interrogatif bool `json:"inte"`
|
||||
ParticipesPasses bool `json:"ppas"`
|
||||
Verbose bool `json:"vmode"`
|
||||
Style bool `json:"style"`
|
||||
Populaire bool `json:"bs"`
|
||||
Pleonasme bool `json:"pleo"`
|
||||
ElisionEuphonie bool `json:"eleu"`
|
||||
AdvNegation bool `json:"neg"`
|
||||
RepetitionParag bool `json:"redon1"`
|
||||
RepetitionPhrase bool `json:"redon2"`
|
||||
Divers bool `json:"misc"`
|
||||
MotsComposes bool `json:"mc"`
|
||||
Dates bool `json:"date"`
|
||||
Debug bool `json:"debug"`
|
||||
IdRule bool `json:"idrule"`
|
||||
}
|
||||
|
||||
type GrammalecteGrammarError struct {
|
||||
Start int `json:"nStart"`
|
||||
End int `json:"nEnd"`
|
||||
LineId string `json:"sLineId"`
|
||||
RuleId string `json:"sRuleId"`
|
||||
Type string `json:"sType"`
|
||||
Colors []int `json:"aColor"`
|
||||
Message string `json:"sMessage"`
|
||||
Suggestions []string `json:"aSuggestions"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type GrammalecteSpellingError struct {
|
||||
I int `json:"i"`
|
||||
Type string `json:"sType"`
|
||||
Value string `json:"sValue"`
|
||||
Start int `json:"nStart"`
|
||||
End int `json:"nEnd"`
|
||||
}
|
||||
|
||||
type GrammalecteData struct {
|
||||
Paragraph int `json:"iparagraph"`
|
||||
Text string `json:"sText"`
|
||||
GrammarErrors []GrammalecteGrammarError `json:"lGrammarErrors"`
|
||||
SpellingErrors []GrammalecteSpellingError `json:"lSpellingErrors"`
|
||||
}
|
||||
|
||||
type GrammalecteResponse struct {
|
||||
Program string `json:"program"`
|
||||
Version string `json:"version"`
|
||||
Lang string `json:"lang"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Data []GrammalecteData `json:"data"`
|
||||
}
|
||||
|
||||
type GrammalecteSuggestions struct {
|
||||
Suggestions []string `json:"suggestions"`
|
||||
}
|
||||
|
||||
func suggest(term string) (suggestions *GrammalecteSuggestions, err error) {
|
||||
form := url.Values{}
|
||||
form.Add("token", term)
|
||||
|
||||
resp, err := http.Post(GRAMMALECTE_LOCAL_URL+"/suggest/fr", "application/x-www-form-urlencoded", strings.NewReader(form.Encode()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
err = dec.Decode(&suggestions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
mdimg = regexp.MustCompile(`!\[([^\]]+)\]\([^)]+\)`)
|
||||
)
|
||||
|
||||
func grammalecte(name string, text string, options *GrammalecteOptions) (errs []error) {
|
||||
// Remove Markdown elements
|
||||
text = mdimg.ReplaceAllString(text, "Image : ${1}")
|
||||
|
||||
form := url.Values{}
|
||||
form.Add("text", text)
|
||||
form.Add("tf", "on")
|
||||
|
||||
if options != nil {
|
||||
d, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
log.Println("Unable to marshall GrammalecteOptions:", err.Error())
|
||||
} else {
|
||||
form.Add("options", string(d))
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := http.Post(GRAMMALECTE_LOCAL_URL+"/gc_text/fr", "application/x-www-form-urlencoded", strings.NewReader(form.Encode()))
|
||||
if err != nil {
|
||||
log.Println("Unable to contact grammalecte server:", err.Error())
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var gresponse GrammalecteResponse
|
||||
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
err = dec.Decode(&gresponse)
|
||||
if err != nil {
|
||||
log.Println("Unable to analyse grammalecte response: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(gresponse.Error) > 0 {
|
||||
log.Println("Grammalecte report an error: ", gresponse.Error)
|
||||
}
|
||||
|
||||
for _, data := range gresponse.Data {
|
||||
for _, serror := range data.SpellingErrors {
|
||||
allowed := false
|
||||
for _, w := range ALLOWED_WORDS {
|
||||
if w == serror.Value {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if allowed {
|
||||
continue
|
||||
}
|
||||
|
||||
suggestions, _ := suggest(serror.Value)
|
||||
errs = append(errs, SpellingError{
|
||||
Prefix: name,
|
||||
Source: data.Text,
|
||||
NSource: data.Paragraph,
|
||||
Start: serror.Start,
|
||||
End: serror.End,
|
||||
Type: serror.Type,
|
||||
Value: serror.Value,
|
||||
Suggestions: suggestions.Suggestions,
|
||||
})
|
||||
}
|
||||
|
||||
for _, gerror := range data.GrammarErrors {
|
||||
if data.Text[0] == '>' && gerror.RuleId == "poncfin_règle1" {
|
||||
continue
|
||||
}
|
||||
|
||||
errs = append(errs, GrammarError{
|
||||
Prefix: name,
|
||||
Source: data.Text,
|
||||
NSource: data.Paragraph,
|
||||
Start: gerror.Start,
|
||||
End: gerror.End,
|
||||
RuleId: gerror.RuleId,
|
||||
Type: gerror.Type,
|
||||
Message: gerror.Message,
|
||||
Suggestions: gerror.Suggestions,
|
||||
URL: gerror.URL,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
Reference in a new issue