Newer
Older
"github.com/andybalholm/cascadia"
"gitlab.schukai.com/oss/libraries/go/markup/html/engine"
"gopkg.in/yaml.v3"
"os"
"path"
"strings"
)
yamlFile, err := os.ReadFile(dataPath)
if err != nil {
return err
}
storage := types.NewPageDataStorage()
if err := yaml.Unmarshal(yamlFile, storage); err != nil {
return err
}
for name, page := range storage {
generatedHtml, err := Generate(page, p)
log.Error("Error " + err.Error() + " while generating " + p)
outFile := path.Join(out, page.Export)
dir := path.Dir(outFile)
if err := os.MkdirAll(dir, 0755); err != nil {
log.Error("Error " + err.Error() + " while creating directory " + dir)
err = os.WriteFile(outFile, []byte(generatedHtml), 0644)
log.Error("Error " + err.Error() + " while writing " + outFile)
return err
}
}
return nil
}
func Generate(data *types.PageData, name string) (string, error) {
dataset := make(map[any]any)
dataset["lang"] = data.Lang
dataset["title"] = data.Title
if data.Title == "" {
log.Warn("No title set for " + name)
}
log.Info("Generating " + data.Export + " with template " + name)
dataset["meta"] = make(map[any]any)
for k, v := range data.Meta {
dataset["meta"].(map[any]any)[k] = v
}
dataset["images"] = make(map[any]any, 0)
for _, v := range data.Images {
dataset["images"].(map[any]any)[v.Id] = map[any]any{
"source": v.Source,
"alt": v.Alt,
"title": v.Title,
"id": v.Id,
}
}
dataset["anchors"] = make(map[any]any, 0)
for _, v := range data.Anchors {
dataset["anchors"].(map[any]any)[v.Id] = map[any]any{
"href": v.Href,
"hreflang": v.HrefLang,
"title": v.Title,
"id": v.Id,
}
}
dataset["text"] = make(map[any]any, 0)
for _, v := range data.Text {
dataset["text"].(map[any]any)[v.Id] = map[any]any{"text": v.Text}
}
dataset["translations"] = make(map[string]any, 0)
for _, v := range data.Translations {
j, err := json.Marshal(v.KeyValues)
if err != nil {
return "", err
}
dataset["translations"].(map[string]any)[v.Id] = map[string]string{
"content": string(j),
}
}
e := engine.New(dataset)
template, err := os.ReadFile(name)
if err != nil {
return "", err
}
stringWriter := &strings.Builder{}
e.ProcessHtml(stringWriter, strings.NewReader(string(template)))
return doModifications(data, stringWriter.String())
}
func doModifications(page *types.PageData, from string) (string, error) {
node, err := html.Parse(strings.NewReader(from))
if err != nil {
return "", err
}
if len(page.Modifications.Remove) == 0 {
log.Info("No remove modifications set for " + page.Export)
} else {
log.Infof("There are %d remove modifications set for %s", len(page.Modifications.Remove), page.Export)
}
for _, m := range page.Modifications.Remove {
selector, err := cascadia.Parse(m)
if err != nil {
return "", err
}
list := cascadia.QueryAll(node, selector)
for _, n := range list {
if n.Parent != nil {
n.Parent.RemoveChild(n)
}
}
if len(page.Modifications.Add) == 0 {
log.Info("No add modifications set for " + page.Export)
} else {
log.Infof("There are %d add modifications set for %s", len(page.Modifications.Add), page.Export)
}
for _, m := range page.Modifications.Add {
selector, err := cascadia.Parse(m.Selector)
if err != nil {
return "", err
}
list := cascadia.QueryAll(node, selector)
for _, n := range list {
if n.Parent != nil {
nodes, err := html.ParseFragment(strings.NewReader(m.Html), n)
if err != nil {
return "", err
}
for _, added := range nodes {
n.InsertBefore(added, n.FirstChild)
}
}
}
}
if len(page.Modifications.SetAttribute) == 0 {
log.Info("No set attribute modifications set for " + page.Export)
} else {
log.Infof("There are %d set attribute modifications set for %s", len(page.Modifications.SetAttribute), page.Export)
}
for _, m := range page.Modifications.SetAttribute {
selector, err := cascadia.Parse(m.Selector)
if err != nil {
return "", err
}
list := cascadia.QueryAll(node, selector)
for _, n := range list {
if n.Parent != nil {
attr := n.Attr
attr = append(attr, html.Attribute{
Key: m.Name,
Val: m.Value,
})
log.Info("Set attribute " + m.Name + " to " + m.Value + " for " + page.Export)
n.Attr = attr
}
}
}
stringWriter := &strings.Builder{}
err = html.Render(stringWriter, node)
if err != nil {
return "", err
}
return stringWriter.String(), nil
func removeAttr(n *html.Node, search string) {
i := -1
for index, attr := range n.Attr {
if attr.Key == search {
i = index
break
}
}
if i != -1 {
n.Attr = append(n.Attr[:i], n.Attr[i+1:]...)
}
}