/*
* Copyright (c) 2013 Dario Castañé.
* This file is part of Zas.
*
* Zas is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Zas is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Zas. If not, see .
*/
package zas
import (
"bytes"
"errors"
"fmt"
thtml "html/template"
"io"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"sync"
"sync/atomic"
ttext "text/template"
"time"
"github.com/PuerkitoBio/goquery"
"github.com/darccio/zas/internal/i18n"
markdown "github.com/yuin/goldmark"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/util"
yaml "go.yaml.in/yaml/v3"
html5 "golang.org/x/net/html"
"golang.org/x/net/html/atom"
)
var helpers = thtml.FuncMap{
"noescape": noescape,
}
// rawHTMLRenderer overrides only goldmark's raw-HTML node kinds (block and
// inline) to pass their source through unchanged, instead of the default
// renderer's "" placeholder. Unlike
// html.WithUnsafe(), this leaves every other renderer - including the ones
// that sanitize link and image destinations against javascript:/data:/etc.
// URLs - on their default, safe behavior. It's registered at a lower
// priority number than the default HTML renderer (1000), which wins ties.
type rawHTMLRenderer struct{}
func (r *rawHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(ast.KindHTMLBlock, r.renderHTMLBlock)
reg.Register(ast.KindRawHTML, r.renderRawHTML)
}
func (r *rawHTMLRenderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*ast.HTMLBlock)
if entering {
for i := 0; i < n.Lines().Len(); i++ {
line := n.Lines().At(i)
_, _ = w.Write(line.Value(source))
}
} else if n.HasClosure() {
_, _ = w.Write(n.ClosureLine.Value(source))
}
return ast.WalkContinue, nil
}
func (r *rawHTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
return ast.WalkSkipChildren, nil
}
n := node.(*ast.RawHTML)
for i := 0; i < n.Segments.Len(); i++ {
segment := n.Segments.At(i)
_, _ = w.Write(segment.Value(source))
}
return ast.WalkSkipChildren, nil
}
// markdownConverter passes raw HTML through instead of dropping it - a
// leading HTML comment (per-page config) and an