91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
|
package rendering
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"html/template"
|
||
|
"regexp"
|
||
|
|
||
|
"github.com/gomarkdown/markdown/parser"
|
||
|
|
||
|
"github.com/baez90/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 := templateRenderBufferPool.Get().(*bytes.Buffer)
|
||
|
defer func() {
|
||
|
buf.Reset()
|
||
|
templateRenderBufferPool.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
|
||
|
}
|