123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- package pgenr
- import (
- "golang.org/x/net/html/atom"
- "html"
- "strings"
- )
- const (
- TextThemeSuccess = "success"
- TextThemeDanger = "danger"
- )
- type (
- TextOption func(t *Text)
- ButtonOption func(btn *Button)
- Text struct {
- Tag atom.Atom
- Content string
- Theme string
- Color string
- Style map[string]string
- }
- Button struct {
- Url string
- Text string
- Color string
- Style map[string]string
- }
- Entry struct {
- Title *Text
- Items map[string]*Text
- }
- Action struct {
- Instructions *Text
- Button *Button
- InviteCode string
- }
- Table struct {
- Title *Text
- Header []*Text
- Body [][]*Text
- }
- Page struct {
- Title string
- Head string
- Intros []*Text
- Entries []*Entry
- Actions []*Action
- Tables []*Table
- Outros []*Text
- Copyright string
- }
- )
- func (e *Entry) AddItem(label string, txt *Text) *Entry {
- if e.Items == nil {
- e.Items = make(map[string]*Text)
- }
- e.Items[label] = txt
- return e
- }
- func (page *Page) SetHead(s string) *Page {
- page.Head = s
- return page
- }
- func (page *Page) SetCopyright(s string) *Page {
- page.Copyright = s
- return page
- }
- func (page *Page) AddPlainIntro(s string) *Page {
- page.Intros = append(page.Intros, NewText(s, WithTextTag(atom.P)))
- return page
- }
- func (page *Page) AddIntro(t *Text) *Page {
- page.Intros = append(page.Intros, t)
- return page
- }
- func (page *Page) AddEntry(e *Entry) *Page {
- page.Entries = append(page.Entries, e)
- return page
- }
- func (page *Page) AddTable(t *Table) *Page {
- page.Tables = append(page.Tables, t)
- return page
- }
- func (page *Page) AddButtonAction(s string, btn *Button) *Page {
- page.Actions = append(page.Actions, &Action{Instructions: NewText(s, WithTextTag(atom.P)), Button: btn})
- return page
- }
- func (page *Page) AddInviteCodeAction(s string, code string) *Page {
- page.Actions = append(page.Actions, &Action{Instructions: NewText(s, WithTextTag(atom.P)), InviteCode: code})
- return page
- }
- func (page *Page) AddOutro(t *Text) *Page {
- page.Outros = append(page.Outros, t)
- return page
- }
- func (page *Page) AddPlainOutro(s string) *Page {
- page.Outros = append(page.Outros, NewText(s, WithTextTag(atom.P)))
- return page
- }
- func (page *Page) Escape() {
- page.Head = html.EscapeString(page.Head)
- page.Copyright = html.EscapeString(page.Copyright)
- }
- func NewPage(title string) *Page {
- return &Page{
- Title: title,
- Intros: make([]*Text, 0),
- Entries: make([]*Entry, 0),
- Actions: make([]*Action, 0),
- Outros: make([]*Text, 0),
- Tables: make([]*Table, 0),
- }
- }
- func NewEntry(title string) *Entry {
- return &Entry{
- Title: NewText(title, WithTextTag(atom.P)),
- Items: make(map[string]*Text),
- }
- }
- func WithTextTheme(s string) TextOption {
- return func(t *Text) {
- t.Theme = s
- }
- }
- func WithTextStyle(ms map[string]string) TextOption {
- return func(t *Text) {
- t.Style = ms
- }
- }
- func WithTextTag(tag atom.Atom) TextOption {
- return func(t *Text) {
- t.Tag = tag
- }
- }
- func WithTextColor(color string) TextOption {
- return func(t *Text) {
- t.Color = color
- }
- }
- func (button *Button) String() string {
- var (
- sb strings.Builder
- )
- if button.Style == nil {
- button.Style = make(map[string]string)
- }
- if button.Color != "" {
- button.Style["color"] = button.Color
- }
- sb.WriteString("<a class='button'")
- if button.Url != "" {
- sb.WriteString(" href='" + button.Url + "'")
- }
- if len(button.Style) > 0 {
- sb.WriteString(" style='")
- for k, v := range button.Style {
- sb.WriteString(k)
- sb.WriteString(":")
- sb.WriteString(v)
- sb.WriteString(";")
- }
- sb.WriteString("'")
- }
- sb.WriteString(">")
- sb.WriteString(html.EscapeString(button.Text))
- sb.WriteString("</a>")
- return sb.String()
- }
- func (table *Table) SetHead(header ...*Text) {
- table.Header = header
- }
- func (table *Table) AddCell(texts ...*Text) {
- if table.Body == nil {
- table.Body = make([][]*Text, 0)
- }
- table.Body = append(table.Body, texts)
- }
- func (table *Table) String() string {
- var (
- sb strings.Builder
- )
- sb.WriteString("<div class='table-wrapper'>")
- if table.Title != nil {
- sb.WriteString("<div class='table-title'>")
- sb.WriteString(table.Title.String())
- sb.WriteString("</div>")
- }
- sb.WriteString("<table class='table'>")
- if len(table.Header) > 0 {
- sb.WriteString("<thead><tr>")
- for _, text := range table.Header {
- sb.WriteString("<th>")
- sb.WriteString(text.String())
- sb.WriteString("</th>")
- }
- sb.WriteString("</tr></thead>")
- }
- if len(table.Body) > 0 {
- sb.WriteString("<tbody>")
- for _, cell := range table.Body {
- sb.WriteString("<tr>")
- for _, text := range cell {
- sb.WriteString("<td>")
- sb.WriteString(text.String())
- sb.WriteString("</td>")
- }
- sb.WriteString("</tr>")
- }
- sb.WriteString("</tbody>")
- }
- sb.WriteString("</table></div>")
- return sb.String()
- }
- func (text *Text) String() string {
- var (
- sb strings.Builder
- )
- if text.Style == nil {
- text.Style = make(map[string]string)
- }
- if text.Color != "" {
- text.Style["color"] = text.Color
- }
- if text.Tag == 0 {
- text.Tag = atom.Span
- }
- sb.WriteString("<")
- sb.WriteString(text.Tag.String())
- if text.Theme != "" {
- sb.WriteString(" class='text-")
- sb.WriteString(text.Theme)
- sb.WriteString("'")
- }
- if len(text.Style) > 0 {
- sb.WriteString(" style='")
- for k, v := range text.Style {
- sb.WriteString(k)
- sb.WriteString(":")
- sb.WriteString(v)
- sb.WriteString(";")
- }
- sb.WriteString("'")
- }
- sb.WriteString(">")
- sb.WriteString(html.EscapeString(text.Content))
- sb.WriteString("</")
- sb.WriteString(text.Tag.String())
- sb.WriteString(">")
- return sb.String()
- }
- func NewButton(label, link string, opts ...ButtonOption) *Button {
- btn := &Button{Text: label, Url: link}
- for _, cb := range opts {
- cb(btn)
- }
- return btn
- }
- func NewText(s string, opts ...TextOption) *Text {
- txt := &Text{Content: s, Tag: atom.Span}
- for _, cb := range opts {
- cb(txt)
- }
- return txt
- }
- func NewTable(title *Text) *Table {
- table := &Table{
- Title: title,
- Header: make([]*Text, 0),
- Body: make([][]*Text, 0),
- }
- return table
- }
|