97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
/*
|
|
* Amsterdam Web Communities System
|
|
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
// The htmlcheck package contains the HTML Checker.
|
|
package htmlcheck
|
|
|
|
import (
|
|
"context"
|
|
_ "embed"
|
|
"os"
|
|
|
|
"git.erbosoft.com/amy/amsterdam/config"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// SpellingDictionary is a simple dictionary interface.
|
|
type SpellingDictionary interface {
|
|
Ready() bool
|
|
Size() int
|
|
CheckWord(string) bool
|
|
}
|
|
|
|
// ModSpellingDictionary is an intrerface to a modifiable spelling dictionary.
|
|
type ModSpellingDictionary interface {
|
|
SpellingDictionary
|
|
AddWord(string)
|
|
DelWord(string)
|
|
Clear()
|
|
}
|
|
|
|
//go:embed en-us.dict
|
|
var mainDict []byte
|
|
|
|
//go:embed supplement.dict
|
|
var supplementaryDict []byte
|
|
|
|
// SetupDicts sets up the dictionaries and the spelling rewriter.
|
|
func SetupDicts() {
|
|
dicts := make([]SpellingDictionary, 2, 3)
|
|
dicts[0] = LoadTrieDict(mainDict)
|
|
dicts[1] = LoadTrieDict(supplementaryDict)
|
|
if config.GlobalConfig.Posting.ExternalDictionary != "" {
|
|
data, err := os.ReadFile(config.GlobalConfig.Posting.ExternalDictionary)
|
|
if err == nil {
|
|
ndict := LoadTrieDict(data)
|
|
dicts = append(dicts, ndict)
|
|
} else {
|
|
log.Errorf("failed to load external dictionary %s: %v", config.GlobalConfig.Posting.ExternalDictionary, err)
|
|
}
|
|
}
|
|
rw := spellingRewriter{
|
|
dict: NewCompositeDict(dicts),
|
|
}
|
|
rewriterRegistry[rw.Name()] = &rw
|
|
}
|
|
|
|
// spellingRewriter is a rewriter that flags spelling errors.
|
|
type spellingRewriter struct {
|
|
dict SpellingDictionary
|
|
}
|
|
|
|
// defaultBeginError is the markup that indicates the start of an error.
|
|
const defaultBeginError = "<span class=\"text-red-600 font-bold\">"
|
|
|
|
// defaultEndError is the markup that indicates the end of an error.
|
|
const defaultEndError = "</span>"
|
|
|
|
// Name returns the rewriter's name.
|
|
func (rw *spellingRewriter) Name() string {
|
|
return "spelling"
|
|
}
|
|
|
|
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
|
* Parameters:
|
|
* ctx - Standard Go error status.
|
|
* data - The data to be rewritten.
|
|
* svc - Services interface we can use.
|
|
* Returns:
|
|
* Pointer to markup data, or nil.
|
|
*/
|
|
func (rw *spellingRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
|
if rw.dict.CheckWord(data) {
|
|
return nil
|
|
}
|
|
return &markupData{
|
|
beginMarkup: defaultBeginError,
|
|
text: data,
|
|
endMarkup: defaultEndError,
|
|
rescan: false,
|
|
}
|
|
}
|