Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

mdlist.gno

3.33 Kb · 119 lines
  1// Package mdlist is a proof-of-concept for composable UIs patterns.
  2//
  3// It allows specifying a data source and then dynamically rendering it as
  4// a list or a grid.
  5package mdlist
  6
  7import (
  8	"strings"
  9
 10	"gno.land/p/moul/md/v0"
 11)
 12
 13// XXX: configurable length UL
 14// XXX: moul/pager.Pager-powered auto mdlist
 15// XXX: func (l List) Render(path string) string {
 16// XXX: add .Table()
 17
 18type Entries []Entry
 19
 20type Entry struct {
 21	// Title is the title of the entry. Required.
 22	Title string
 23	// Body is the body of the entry. Required.
 24	Body string
 25	// Link is the URL of the entry. Optional.
 26	Link string
 27	// Links is a list of additional URLs of the entry. Optional.
 28	Links []string
 29}
 30
 31// BulletList returns entries as a markdown bullet list without truncation.
 32func (l Entries) BulletList() string {
 33	return l.BulletListTruncated(-1, -1)
 34}
 35
 36// BulletListTruncated returns entries as a markdown bullet list with truncation.
 37func (l Entries) BulletListTruncated(titleMaxLength, bodyMaxLength int) string {
 38	items := make([]string, len(l))
 39	for i, entry := range l {
 40		title := truncateText(entry.Title, titleMaxLength, false)
 41		if entry.Link != "" {
 42			title = md.Link(title, entry.Link)
 43		}
 44		body := truncateText(entry.Body, bodyMaxLength, true)
 45		links := strings.Join(entry.Links, " ")
 46		item := md.Bold(title) + ": " + md.Italic(body) + " " + links
 47		items[i] = strings.TrimSpace(item)
 48	}
 49	return md.BulletList(items)
 50}
 51
 52// NumberedList returns entries as a markdown numbered list without truncation.
 53func (l Entries) NumberedList() string {
 54	return l.NumberedListTruncated(-1, -1)
 55}
 56
 57// NumberedListTruncated returns entries as a markdown numbered list with truncation.
 58func (l Entries) NumberedListTruncated(titleMaxLength, bodyMaxLength int) string {
 59	items := make([]string, len(l))
 60	for i, entry := range l {
 61		title := truncateText(entry.Title, titleMaxLength, false)
 62		if entry.Link != "" {
 63			title = md.Link(title, entry.Link)
 64		}
 65		body := truncateText(entry.Body, bodyMaxLength, true)
 66		links := strings.Join(entry.Links, " ")
 67		item := md.Bold(title) + ": " + md.Italic(body) + " " + links
 68		items[i] = strings.TrimSpace(item)
 69	}
 70	return md.OrderedList(items)
 71}
 72
 73// Paragraphs returns entries as simple paragraphs with bold titles.
 74func (l Entries) Paragraphs() string {
 75	paragraphs := make([]string, len(l))
 76	for i, entry := range l {
 77		title := entry.Title
 78		if entry.Link != "" {
 79			title = md.Link(title, entry.Link)
 80		}
 81		paragraph := md.Bold(title) + ". " + entry.Body
 82		if len(entry.Links) > 0 {
 83			paragraph += " " + strings.Join(entry.Links, " ")
 84		}
 85		paragraphs[i] = paragraph
 86	}
 87	return strings.Join(paragraphs, "\n\n")
 88}
 89
 90func (l Entries) Columns() string {
 91	columns := make([]string, len(l))
 92	for i, entry := range l {
 93		title := entry.Title
 94		if entry.Link != "" {
 95			title = md.Link(title, entry.Link)
 96		}
 97		body := entry.Body
 98		links := strings.Join(entry.Links, " ")
 99		columns[i] = md.H2(title) + md.Paragraph(body) + md.Paragraph(links)
100	}
101	return md.Columns(columns, false)
102}
103
104func truncateText(content string, maxLength int, withNewLines bool) string {
105	// If maxLength is -1, don't truncate
106	if maxLength < 0 {
107		if !withNewLines {
108			content = strings.ReplaceAll(content, "\n", " ")
109		}
110		return content
111	}
112	if !withNewLines {
113		content = strings.ReplaceAll(content, "\n", " ")
114	}
115	if len(content) > maxLength {
116		return content[:maxLength-3] + "..."
117	}
118	return content
119}