beginnings of HTML checker - added struct and interface defs, emoticon rewriter
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// HTMLChecker is a component that checks HTML and reformats it as needed.
|
||||
type HTMLChecker interface {
|
||||
Append(string) error
|
||||
Finish() error
|
||||
Reset()
|
||||
Value() (string, error)
|
||||
Length() (int, error)
|
||||
Lines() (int, error)
|
||||
Counter(string) (int, error)
|
||||
Context() map[string]any
|
||||
ExternalRefs() ([]any, error)
|
||||
InternalRefs() ([]any, error)
|
||||
}
|
||||
|
||||
// var NotYetFinished = errors.New("the HTML checker has not yet been finished")
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 (
|
||||
_ "embed"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// EmoticonDef is a single emoticon definition.
|
||||
type EmoticonDef struct {
|
||||
Name string `yaml:"name"`
|
||||
Patterns []string `yaml:"patterns"`
|
||||
Replace string `yaml:"replace"`
|
||||
}
|
||||
|
||||
// EmoticonConfig is the YAML configuration of the emoticons.
|
||||
type EmoticonConfig struct {
|
||||
PrefixChars string `yaml:"prefixChars"`
|
||||
Emoticons []EmoticonDef `yaml:"emoticons"`
|
||||
}
|
||||
|
||||
// emoticonRewriter is the implementation of rewriter in this file
|
||||
type emoticonRewriter struct {
|
||||
config *EmoticonConfig
|
||||
prefixChars []byte
|
||||
emos map[string]*EmoticonDef
|
||||
patterns map[string]string
|
||||
minLength int
|
||||
}
|
||||
|
||||
//go:embed emoticons.yaml
|
||||
var rawEmoConfig []byte
|
||||
|
||||
// EmoticonRewriter is the singleton instance of the emoticon rewriter.
|
||||
var EmoticonRewriter rewriter
|
||||
|
||||
// init loads the configuration and creates the singleton instance.
|
||||
func init() {
|
||||
var cfg EmoticonConfig
|
||||
if err := yaml.Unmarshal(rawEmoConfig, &cfg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rw := emoticonRewriter{
|
||||
config: &cfg,
|
||||
prefixChars: []byte(cfg.PrefixChars),
|
||||
emos: make(map[string]*EmoticonDef),
|
||||
patterns: make(map[string]string),
|
||||
minLength: math.MaxInt,
|
||||
}
|
||||
for i, def := range rw.config.Emoticons {
|
||||
rw.emos[def.Name] = &(rw.config.Emoticons[i])
|
||||
for _, p := range def.Patterns {
|
||||
f := false
|
||||
for k := range rw.prefixChars {
|
||||
if p[0] == rw.prefixChars[k] {
|
||||
f = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if f {
|
||||
rw.patterns[p] = def.Name
|
||||
rw.minLength = min(rw.minLength, len(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
EmoticonRewriter = &rw
|
||||
}
|
||||
|
||||
// Name returns the rewriter's name.
|
||||
func (rw *emoticonRewriter) Name() string {
|
||||
return "emoticon"
|
||||
}
|
||||
|
||||
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
||||
* Parameters:
|
||||
* data - The data to be rewritten.
|
||||
* svc - Services interface we can use.
|
||||
* Returns:
|
||||
* Pointer to markup data, or nil.
|
||||
*/
|
||||
func (rw *emoticonRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
||||
pos := math.MaxInt
|
||||
for _, c := range rw.prefixChars {
|
||||
foo := strings.IndexByte(data, c)
|
||||
if foo >= 0 {
|
||||
pos = min(pos, foo)
|
||||
}
|
||||
}
|
||||
if pos == math.MaxInt {
|
||||
return nil
|
||||
}
|
||||
didReplace := false
|
||||
var output strings.Builder
|
||||
work := data
|
||||
for pos != math.MaxInt {
|
||||
if pos > 0 {
|
||||
output.WriteString(work[:pos])
|
||||
work = work[pos:]
|
||||
}
|
||||
looking := true
|
||||
if len(work) >= rw.minLength {
|
||||
for k, v := range rw.patterns {
|
||||
if strings.HasPrefix(work, k) {
|
||||
looking = false
|
||||
output.WriteString(rw.emos[v].Replace)
|
||||
work = work[len(k):]
|
||||
didReplace = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if looking {
|
||||
output.WriteString(work[:1])
|
||||
work = work[1:]
|
||||
}
|
||||
pos = math.MaxInt
|
||||
for _, c := range rw.prefixChars {
|
||||
foo := strings.IndexByte(work, c)
|
||||
if foo >= 0 {
|
||||
pos = min(pos, foo)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !didReplace {
|
||||
return nil
|
||||
}
|
||||
output.WriteString(work)
|
||||
return &markupData{beginMarkup: "", text: output.String(), endMarkup: "", rescan: true}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
prefixChars: ":;"
|
||||
emoticons:
|
||||
- name: smile
|
||||
patterns:
|
||||
- ":)"
|
||||
replace: "😊"
|
||||
- name: frown
|
||||
patterns:
|
||||
- ":("
|
||||
replace: "🙁"
|
||||
- name: redface
|
||||
patterns:
|
||||
- ":o"
|
||||
- ":O"
|
||||
replace: "😳"
|
||||
- name: biggrin
|
||||
patterns:
|
||||
":D"
|
||||
replace: "😁"
|
||||
- name: wink
|
||||
patterns:
|
||||
- ";)"
|
||||
replace: "😉"
|
||||
- name: tongue
|
||||
patterns:
|
||||
- ":p"
|
||||
- ":P"
|
||||
replace: "😛"
|
||||
- name: cool
|
||||
patterns:
|
||||
- ":cool:"
|
||||
replace: "😎"
|
||||
- name: rolleyes
|
||||
patterns:
|
||||
- ":rolleyes:"
|
||||
replace: "🙄"
|
||||
- name: mad
|
||||
patterns:
|
||||
- ":mad:"
|
||||
replace: "😡"
|
||||
- name: eek
|
||||
patterns:
|
||||
":eek:"
|
||||
replace: "😱"
|
||||
- name: confused
|
||||
patterns:
|
||||
":confused:"
|
||||
replace: "😕"
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 "net/url"
|
||||
|
||||
type markupData struct {
|
||||
beginMarkup string
|
||||
text string
|
||||
endMarkup string
|
||||
rescan bool
|
||||
}
|
||||
|
||||
type rewriterServices interface {
|
||||
rewriterAttrValue(string) string
|
||||
rewriterContextValue(string) any
|
||||
addExternalRef(url.URL)
|
||||
addInternalRef(string)
|
||||
}
|
||||
|
||||
type rewriter interface {
|
||||
Name() string
|
||||
Rewrite(string, rewriterServices) *markupData
|
||||
}
|
||||
Reference in New Issue
Block a user