12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package gemtext
- import (
- "servitor/style"
- "regexp"
- "strings"
- )
- type Markup struct {
- tree []string
- cached string
- cachedWidth int
- }
- func NewMarkup(text string) (*Markup, []string, error) {
- lines := strings.Split(text, "\n")
- rendered, links := renderWithLinks(lines, 80)
- return &Markup{
- tree: lines,
- cached: rendered,
- cachedWidth: 80,
- }, links, nil
- }
- func (m *Markup) Render(width int) string {
- if m.cachedWidth == width {
- return m.cached
- }
- rendered, _ := renderWithLinks(m.tree, width)
- m.cached = rendered
- m.cachedWidth = width
- return rendered
- }
- func renderWithLinks(lines []string, width int) (string, []string) {
- links := []string{}
- result := ""
- preformattedMode := false
- preformattedBuffer := ""
- for _, line := range lines {
- if strings.HasPrefix(line, "```") {
- if preformattedMode {
- result += style.CodeBlock(strings.TrimSuffix(preformattedBuffer, "\n")) + "\n"
- preformattedBuffer = ""
- preformattedMode = false
- } else {
- preformattedMode = true
- }
- continue
- }
- if preformattedMode {
- preformattedBuffer += line + "\n"
- continue
- }
- if match := regexp.MustCompile(`^=>[ \t]*(.*?)(?:[ \t]+(.*))?$`).FindStringSubmatch(line); len(match) == 3 {
- uri := match[1]
- alt := match[2]
- if alt == "" {
- alt = uri
- }
- links = append(links, uri)
- result += style.LinkBlock(alt, len(links)) + "\n"
- } else if match := regexp.MustCompile(`^#[ \t]+(.*)$`).FindStringSubmatch(line); len(match) == 2 {
- result += style.Header(match[1], 1) + "\n"
- } else if match := regexp.MustCompile(`^##[ \t]+(.*)$`).FindStringSubmatch(line); len(match) == 2 {
- result += style.Header(match[1], 2) + "\n"
- } else if match := regexp.MustCompile(`^###[ \t]+(.*)$`).FindStringSubmatch(line); len(match) == 2 {
- result += style.Header(match[1], 3) + "\n"
- } else if match := regexp.MustCompile(`^\* (.*)$`).FindStringSubmatch(line); len(match) == 2 {
- result += style.Bullet(match[1]) + "\n"
- } else if match := regexp.MustCompile(`^> ?(.*)$`).FindStringSubmatch(line); len(match) == 2 {
- result += style.QuoteBlock(match[1]) + "\n"
- } else {
- result += line + "\n"
- }
- }
-
- if preformattedMode {
- result += style.CodeBlock(strings.TrimSuffix(preformattedBuffer, "\n")) + "\n"
- }
- return strings.Trim(result, "\n"), links
- }
|