90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package rendering
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"regexp"
|
|
|
|
"github.com/gomarkdown/markdown/parser"
|
|
"github.com/valyala/bytebufferpool"
|
|
|
|
"code.icb4dc0.de/prskr/goveal/config"
|
|
)
|
|
|
|
const (
|
|
parserExtensions = parser.NoIntraEmphasis | parser.Tables | parser.FencedCode |
|
|
parser.Autolink | parser.Strikethrough | parser.SpaceHeadings | parser.HeadingIDs |
|
|
parser.BackslashLineBreak | parser.DefinitionLists | parser.MathJax | parser.Titleblock |
|
|
parser.OrderedListStart | parser.Attributes
|
|
)
|
|
|
|
func ToHTML(markdown string, renderCfg config.Rendering) (rendered []byte, err error) {
|
|
var slides []rawSlide
|
|
if slides, err = splitIntoRawSlides(markdown, renderCfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
buf := bytebufferpool.Get()
|
|
defer func() {
|
|
buf.Reset()
|
|
bytebufferpool.Put(buf)
|
|
}()
|
|
|
|
for idx := range slides {
|
|
if rendered, err := slides[idx].ToHTML(); err != nil {
|
|
return nil, err
|
|
} else {
|
|
_, _ = buf.WriteString(string(rendered))
|
|
}
|
|
}
|
|
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
type rawSlide struct {
|
|
Content string
|
|
Children []rawSlide
|
|
}
|
|
|
|
func (s rawSlide) HasNotes() bool {
|
|
return notesLineRegexp.MatchString(s.Content)
|
|
}
|
|
|
|
func (s rawSlide) ToHTML() (template.HTML, error) {
|
|
if rendered, err := renderTemplate("slide.gohtml", s); err != nil {
|
|
return "", err
|
|
} else {
|
|
//nolint:gosec // should not be sanitized
|
|
return template.HTML(rendered), nil
|
|
}
|
|
}
|
|
|
|
func splitIntoRawSlides(markdown string, renderCfg config.Rendering) ([]rawSlide, error) {
|
|
var (
|
|
verticalSplit, horizontalSplit *regexp.Regexp
|
|
err error
|
|
)
|
|
if verticalSplit, err = regexp.Compile(fmt.Sprintf(splitFormat, renderCfg.VerticalSeparator)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if horizontalSplit, err = regexp.Compile(fmt.Sprintf(splitFormat, renderCfg.HorizontalSeparator)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
horizontalSlides := horizontalSplit.Split(markdown, -1)
|
|
slides := make([]rawSlide, 0, len(horizontalSlides))
|
|
for _, hs := range horizontalSlides {
|
|
s := rawSlide{
|
|
Content: hs,
|
|
}
|
|
verticalSlides := verticalSplit.Split(hs, -1)
|
|
s.Children = make([]rawSlide, 0, len(verticalSlides))
|
|
for _, vs := range verticalSlides {
|
|
s.Children = append(s.Children, rawSlide{Content: vs})
|
|
}
|
|
slides = append(slides, s)
|
|
}
|
|
|
|
return slides, nil
|
|
}
|