.
func (r Rich) Code() Rich { return "" + r + "" }
// Mark wraps the fragment in .
func (r Rich) Mark() Rich { return "" + r + "" }
// Sub wraps the fragment in .
func (r Rich) Sub() Rich { return "" + r + "" }
// Sup wraps the fragment in .
func (r Rich) Sup() Rich { return "" + r + "" }
// Spoiler wraps the fragment in .
func (r Rich) Spoiler() Rich { return "" + r + " " }
// Link wraps the fragment in a hyperlink to url.
func (r Rich) Link(url string) Rich { return `` + r + "" }
// Email wraps the fragment in a mailto: link.
func (r Rich) Email(email string) Rich { return r.Link("mailto:" + email) }
// Phone wraps the fragment in a tel: link.
func (r Rich) Phone(phone string) Rich { return r.Link("tel:" + phone) }
// Mention wraps the fragment in an inline user mention link.
func (r Rich) Mention(userID int64) Rich {
return r.Link("tg://user?id=" + strconv.FormatInt(userID, 10))
}
// Anchor marks the fragment as a named anchor ().
func (r Rich) Anchor(name string) Rich { return `` + r + "" }
// AnchorLink wraps the fragment in an in-document link to a named anchor
// or reference; the server resolves which one by the target name.
func (r Rich) AnchorLink(anchor string) Rich { return r.Link("#" + anchor) }
// Ref wraps the fragment in a to the named reference.
func (r Rich) Ref(ref string) Rich {
return `` + r + " "
}
// Emoji builds a custom emoji fragment with alt text as fallback.
func Emoji(emojiID, alt string) Rich {
return `` + escapeRich(alt) + ` `
}
// Time marks the fragment as a bound to t.
func (r Rich) Time(t time.Time) Rich {
return `` + r + " "
}
// TimeFormat marks the fragment as a with an explicit display format.
func (r Rich) TimeFormat(t time.Time, format string) Rich {
return `` + r + " "
}
// Math wraps the fragment in an inline expression.
func (r Rich) Math() Rich { return `` + r + ` ` }
// Br returns a line break fragment.
func Br() Rich { return "
" }
// H1 builds a level-1 heading block.
func H1(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// H2 builds a level-2 heading block.
func H2(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// H3 builds a level-3 heading block.
func H3(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// H4 builds a level-4 heading block.
func H4(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// H5 builds a level-5 heading block.
func H5(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// H6 builds a level-6 heading block.
func H6(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// P builds a paragraph block.
func P(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// Pre builds a preformatted code block.
func Pre(items ...Rich) RichBlock { return RichBlock("" + richJoin(items...) + "
") }
// PreCode builds a preformatted code block tagged with a language.
func PreCode(lang string, items ...Rich) RichBlock {
return RichBlock(`` + richJoin(items...) + `
`)
}
// Footer builds a footer block.
func Footer(items ...Rich) RichBlock { return RichBlock("") }
// Hr builds a divider block.
func Hr() RichBlock { return "
" }
// AnchorBlock builds a standalone named anchor between blocks: .
func AnchorBlock(name string) RichBlock {
return RichBlock(``)
}
// LiItem is a list item under construction for Ul or Ol.
type LiItem struct {
text Rich
value int
typ string
checkbox bool
checked bool
}
// Li builds a list item from inline fragments.
func Li(items ...Rich) LiItem { return LiItem{text: richJoin(items...)} }
// LiCheckbox builds a checkbox list item.
func LiCheckbox(checked bool, items ...Rich) LiItem {
return LiItem{text: richJoin(items...), checkbox: true, checked: checked}
}
// SetValue sets the explicit ordinal of the item (like ).
func (l LiItem) SetValue(val int) LiItem {
l.value = val
return l
}
// SetType sets the numbering type of the item: "1", "a", "A", "i", "I".
func (l LiItem) SetType(t string) LiItem {
l.typ = t
return l
}
func (l LiItem) build() Rich {
if l.checkbox {
input := Rich(``)
if l.checked {
input = ``
}
return " " + input + l.text + " "
}
attrs := make([]string, 0, 2)
if l.value != 0 {
attrs = append(attrs, `value="`+strconv.Itoa(l.value)+`"`)
}
if l.typ != "" {
attrs = append(attrs, `type="`+escapeHTML(l.typ)+`"`)
}
return Rich(openTag("li", attrs)) + l.text + ""
}
func joinLiItems(items []LiItem) Rich {
var out Rich
for _, item := range items {
out += item.build()
}
return out
}
// Ul builds an unordered list block.
func Ul(items ...LiItem) RichBlock {
return RichBlock(`` + joinLiItems(items) + `
`)
}
// OlOpts holds the numbering attributes.
type OlOpts struct {
Start int
Type string
Reversed bool
}
// Ol builds an ordered list block. Item labels are rendered by the server.
func Ol(opts OlOpts, items ...LiItem) RichBlock {
attrs := make([]string, 0, 3)
if opts.Start > 0 {
attrs = append(attrs, `start="`+strconv.Itoa(opts.Start)+`"`)
}
if opts.Type != "" {
attrs = append(attrs, `type="`+escapeHTML(opts.Type)+`"`)
}
if opts.Reversed {
attrs = append(attrs, "reversed")
}
return RichBlock(openTag("ol", attrs) + string(joinLiItems(items)) + "
")
}
// Blockquote builds a block quotation: lines are joined with
(as in the
// official HTML example) and credit renders as a trailing .
func Blockquote(credit Rich, lines ...Rich) RichBlock {
return RichBlock(`` + richJoinSep(Br(), lines...) + cite(credit) + `
`)
}
// Aside builds a pull quote (