FILE / ScuroNeko/Laniakea

tgrich/input_fmt.go

Исходный файл и его история в репозитории.
FILE dev
Files
ScuroNeko f03a081ed6
Golang lint / lint (pull_request) Successful in 1m20s
Golang lint / lint (push) Successful in 4m8s
(new): rich message support
(fix): runtime reliability
(tests): regression coverage
(doc): v1.1 release notes
2026-08-12 16:34:44 +03:00

571 lines
16 KiB
Go

package tgrich
import "git.scuroneko.dev/scuroneko/laniakea/tgapi"
// Caption creates a media-block caption without a credit.
//
// Since: Bot API 10.2
func Caption(text tgapi.RichText) tgapi.RichBlockCaption { return tgapi.RichBlockCaption{Text: text} }
// CaptionWithCredit creates a media-block caption with a credit.
//
// Since: Bot API 10.2
func CaptionWithCredit(text, credit tgapi.RichText) tgapi.RichBlockCaption {
return tgapi.RichBlockCaption{Text: text, Credit: credit}
}
// P creates a text paragraph corresponding to the HTML <p> tag.
//
// Since: Bot API 10.2
func P(text tgapi.RichText) tgapi.InputRichBlockParagraph {
return tgapi.InputRichBlockParagraph{Type: tgapi.InputRichTypeParagraph, Text: text}
}
// H creates a section heading with a relative font size from 1 (largest) to 6 (smallest).
//
// Since: Bot API 10.2
func H(text tgapi.RichText, size uint8) tgapi.InputRichBlockSectionHeading {
return tgapi.InputRichBlockSectionHeading{
Type: tgapi.InputRichTypeSectionHeading,
Text: text, Size: size,
}
}
// H1 creates a level-one section heading.
//
// Since: Bot API 10.2
func H1(text tgapi.RichText) tgapi.InputRichBlockSectionHeading { return H(text, 1) }
// H2 creates a level-two section heading.
//
// Since: Bot API 10.2
func H2(text tgapi.RichText) tgapi.InputRichBlockSectionHeading { return H(text, 2) }
// H3 creates a level-three section heading.
//
// Since: Bot API 10.2
func H3(text tgapi.RichText) tgapi.InputRichBlockSectionHeading { return H(text, 3) }
// H4 creates a level-four section heading.
//
// Since: Bot API 10.2
func H4(text tgapi.RichText) tgapi.InputRichBlockSectionHeading { return H(text, 4) }
// H5 creates a level-five section heading.
//
// Since: Bot API 10.2
func H5(text tgapi.RichText) tgapi.InputRichBlockSectionHeading { return H(text, 5) }
// H6 creates a level-six section heading.
//
// Since: Bot API 10.2
func H6(text tgapi.RichText) tgapi.InputRichBlockSectionHeading { return H(text, 6) }
// Pre creates a preformatted text block without a programming language.
//
// Since: Bot API 10.2
func Pre(text tgapi.RichText) tgapi.InputRichBlockPreformatted {
return tgapi.InputRichBlockPreformatted{Type: tgapi.InputRichTypePre, Text: text}
}
// CodeBlock creates a preformatted text block with its programming language.
//
// Since: Bot API 10.2
func CodeBlock(text tgapi.RichText, lang string) tgapi.InputRichBlockPreformatted {
return tgapi.InputRichBlockPreformatted{Type: tgapi.InputRichTypePre, Text: text, Language: lang}
}
// Footer creates a footer block.
//
// Since: Bot API 10.2
func Footer(text tgapi.RichText) tgapi.InputRichBlockFooter {
return tgapi.InputRichBlockFooter{Type: tgapi.InputRichTypeFooter, Text: text}
}
// Hr creates a divider corresponding to the HTML <hr/> tag.
//
// Since: Bot API 10.2
func Hr() tgapi.InputRichBlockDivider {
return tgapi.InputRichBlockDivider{Type: tgapi.InputRichTypeDivider}
}
// Math creates a mathematical expression block from a LaTeX expression.
//
// Since: Bot API 10.2
func Math(expression string) tgapi.InputRichBlockMath {
return tgapi.InputRichBlockMath{Type: tgapi.InputRichTypeMathematicalExpression, Expression: expression}
}
// Anchor creates a block containing an anchor with the given name.
//
// Since: Bot API 10.2
func Anchor(name string) tgapi.InputRichBlockAnchor {
return tgapi.InputRichBlockAnchor{Type: tgapi.InputRichTypeAnchor, Name: name}
}
// ListItem builds an input rich-message list item.
//
// Since: Bot API 10.2
type ListItem struct {
blocks []tgapi.InputRichBlock
hasCheckbox bool
isChecked bool
value int
t tgapi.RichBlockListItemType
}
// NewListItem creates a list-item builder containing blocks.
//
// Since: Bot API 10.2
func NewListItem(blocks ...tgapi.InputRichBlock) *ListItem {
return &ListItem{blocks: blocks}
}
// SetBlocks replaces the blocks in the list item.
//
// Since: Bot API 10.2
func (i *ListItem) SetBlocks(blocks ...tgapi.InputRichBlock) *ListItem {
i.blocks = blocks
return i
}
// SetCheckbox adds an unchecked checkbox to the list item.
//
// Since: Bot API 10.2
func (i *ListItem) SetCheckbox() *ListItem {
i.hasCheckbox = true
return i
}
// SetChecked marks the list item's checkbox as checked.
//
// Since: Bot API 10.2
func (i *ListItem) SetChecked() *ListItem {
i.isChecked = true
return i
}
// SetValue sets the explicit number of an ordered-list item.
//
// Since: Bot API 10.2
func (i *ListItem) SetValue(val int) *ListItem {
i.value = val
return i
}
// SetType sets the marker style of an ordered-list item.
//
// Since: Bot API 10.2
func (i *ListItem) SetType(t tgapi.RichBlockListItemType) *ListItem {
i.t = t
return i
}
// Build returns the configured input rich-message list item.
//
// Since: Bot API 10.2
func (i *ListItem) Build() tgapi.InputRichBlockListItem {
return tgapi.InputRichBlockListItem{
Blocks: i.blocks,
HasCheckbox: i.hasCheckbox,
IsChecked: i.isChecked,
Value: i.value,
Type: i.t,
}
}
// List creates a list block from fully configured items.
//
// Since: Bot API 10.2
func List(items ...tgapi.InputRichBlockListItem) tgapi.InputRichBlockList {
return tgapi.InputRichBlockList{Type: tgapi.InputRichTypeList, Items: items}
}
// Ul creates an unordered list and clears ordered-list attributes.
//
// Since: Bot API 10.2
func Ul(items ...tgapi.InputRichBlockListItem) tgapi.InputRichBlockList {
newItems := make([]tgapi.InputRichBlockListItem, len(items))
for index, item := range items {
newItems[index] = tgapi.InputRichBlockListItem{
Blocks: item.Blocks,
HasCheckbox: item.HasCheckbox,
IsChecked: item.IsChecked,
}
}
return List(newItems...)
}
// OlOpts configures ordered-list numbering.
//
// Since: Bot API 10.2
type OlOpts struct {
// Type is the marker style: "1", "a", "A", "i", or "I".
Type tgapi.RichBlockListItemType
// Start is the number of the first item; values below 1 use the default.
Start int
// IsReversed reports whether numbering decreases from Start.
IsReversed bool
}
// Ol creates an ordered list using opts for numbering.
//
// Since: Bot API 10.2
func Ol(opts OlOpts, items ...tgapi.InputRichBlockListItem) tgapi.InputRichBlockList {
newItems := make([]tgapi.InputRichBlockListItem, len(items))
start := opts.Start
if start < 1 {
start = 1
if opts.IsReversed {
start = len(items)
}
}
typ := opts.Type
if typ == "" {
typ = tgapi.InputRichBlockListItemTypeDecimal
}
for index, item := range items {
val := index + start
if opts.IsReversed {
val = start - index
}
newItems[index] = tgapi.InputRichBlockListItem{
Blocks: item.Blocks,
HasCheckbox: item.HasCheckbox,
IsChecked: item.IsChecked,
Value: val,
Type: typ,
}
}
return List(newItems...)
}
// BlockQuote creates a block quotation without a credit.
//
// Since: Bot API 10.2
func BlockQuote(blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockBlockQuotation {
return tgapi.InputRichBlockBlockQuotation{Type: tgapi.InputRichTypeBlockQuotation, Blocks: blocks}
}
// BlockQuoteWithCredit creates a block quotation with a credit.
//
// Since: Bot API 10.2
func BlockQuoteWithCredit(credit tgapi.RichText, blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockBlockQuotation {
return tgapi.InputRichBlockBlockQuotation{Type: tgapi.InputRichTypeBlockQuotation, Blocks: blocks, Credit: &credit}
}
// PullQuote creates a centered quotation without a credit.
//
// Since: Bot API 10.2
func PullQuote(text tgapi.RichText) tgapi.InputRichBlockPullQuotation {
return tgapi.InputRichBlockPullQuotation{Type: tgapi.InputRichTypePullQuotation, Text: text}
}
// PullQuoteWithCredit creates a centered quotation with a credit.
//
// Since: Bot API 10.2
func PullQuoteWithCredit(text tgapi.RichText, credit tgapi.RichText) tgapi.InputRichBlockPullQuotation {
return tgapi.InputRichBlockPullQuotation{Type: tgapi.InputRichTypePullQuotation, Text: text, Credit: &credit}
}
// Collage creates a media collage without a caption.
//
// Since: Bot API 10.2
func Collage(blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockCollage {
return tgapi.InputRichBlockCollage{Type: tgapi.InputRichTypeCollage, Blocks: blocks}
}
// CollageWithCaption creates a media collage with a caption.
//
// Since: Bot API 10.2
func CollageWithCaption(caption tgapi.RichBlockCaption, blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockCollage {
return tgapi.InputRichBlockCollage{Type: tgapi.InputRichTypeCollage, Blocks: blocks, Caption: &caption}
}
// Slideshow creates a media slideshow without a caption.
//
// Since: Bot API 10.2
func Slideshow(blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockSlideshow {
return tgapi.InputRichBlockSlideshow{Type: tgapi.InputRichTypeSlideshow, Blocks: blocks}
}
// SlideshowWithCaption creates a media slideshow with a caption.
//
// Since: Bot API 10.2
func SlideshowWithCaption(caption tgapi.RichBlockCaption, blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockSlideshow {
return tgapi.InputRichBlockSlideshow{Type: tgapi.InputRichTypeSlideshow, Blocks: blocks, Caption: &caption}
}
// TableCell builds a rich-message table cell.
//
// Since: Bot API 10.2
type TableCell struct {
text tgapi.RichText
isHeader bool
colSpan int
rowSpan int
align string
vAlign string
}
// Cell creates an empty table-cell builder.
//
// Since: Bot API 10.2
func Cell() *TableCell { return &TableCell{} }
// CellWithText creates a table-cell builder containing text.
//
// Since: Bot API 10.2
func CellWithText(text tgapi.RichText) *TableCell { return &TableCell{text: text} }
// SetText replaces the text in the table cell.
//
// Since: Bot API 10.2
func (c *TableCell) SetText(text tgapi.RichText) *TableCell {
c.text = text
return c
}
// SetHeader marks the cell as a table header.
//
// Since: Bot API 10.2
func (c *TableCell) SetHeader() *TableCell {
c.isHeader = true
return c
}
// SetSpan sets the cell's column and row spans.
//
// Since: Bot API 10.2
func (c *TableCell) SetSpan(col, row int) *TableCell {
c.colSpan = col
c.rowSpan = row
return c
}
// SetAlign sets horizontal alignment to left, center, or right.
//
// Since: Bot API 10.2
func (c *TableCell) SetAlign(align string) *TableCell {
c.align = align
return c
}
// SetVAlign sets vertical alignment to top, middle, or bottom.
//
// Since: Bot API 10.2
func (c *TableCell) SetVAlign(vAlign string) *TableCell {
c.vAlign = vAlign
return c
}
// Build returns the configured rich-message table cell.
//
// Since: Bot API 10.2
func (c *TableCell) Build() tgapi.RichBlockTableCell {
return tgapi.RichBlockTableCell{
Text: c.text,
IsHeader: c.isHeader,
ColSpan: c.colSpan,
RowSpan: c.rowSpan,
Align: c.align,
VAlign: c.vAlign,
}
}
// Row creates a table row containing cells.
//
// Since: Bot API 10.2
func Row(cells ...tgapi.RichBlockTableCell) []tgapi.RichBlockTableCell {
return cells
}
// RichTable builds an input rich-message table block.
//
// Since: Bot API 10.2
type RichTable struct {
// Cells contains table rows and their cells.
Cells [][]tgapi.RichBlockTableCell
// IsBordered reports whether the table has borders.
IsBordered bool
// IsStriped reports whether the table has striped rows.
IsStriped bool
// Caption is the optional table caption.
Caption *tgapi.RichText
}
// NewTable creates a table builder containing rows.
//
// Since: Bot API 10.2
func NewTable(rows ...[]tgapi.RichBlockTableCell) *RichTable {
return &RichTable{Cells: rows}
}
// AddRows appends rows to the table.
//
// Since: Bot API 10.2
func (t *RichTable) AddRows(rows ...[]tgapi.RichBlockTableCell) *RichTable {
t.Cells = append(t.Cells, rows...)
return t
}
// SetBordered controls whether the table has borders.
//
// Since: Bot API 10.2
func (t *RichTable) SetBordered(b bool) *RichTable {
t.IsBordered = b
return t
}
// SetStriped controls whether the table has striped rows.
//
// Since: Bot API 10.2
func (t *RichTable) SetStriped(b bool) *RichTable {
t.IsStriped = b
return t
}
// SetCaption sets the table caption.
//
// Since: Bot API 10.2
func (t *RichTable) SetCaption(cap *tgapi.RichText) *RichTable {
t.Caption = cap
return t
}
// Build returns the configured input rich-message table.
//
// Since: Bot API 10.2
func (t *RichTable) Build() tgapi.InputRichBlockTable {
return tgapi.InputRichBlockTable{
Type: tgapi.InputRichTypeTable,
Cells: t.Cells,
IsBordered: t.IsBordered,
IsStriped: t.IsStriped,
Caption: t.Caption,
}
}
// Details creates a collapsed details block.
//
// Since: Bot API 10.2
func Details(sum tgapi.RichText, blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockDetails {
return tgapi.InputRichBlockDetails{Type: tgapi.InputRichTypeDetails, Summary: sum, Blocks: blocks}
}
// DetailsOpen creates a details block expanded by default.
//
// Since: Bot API 10.2
func DetailsOpen(sum tgapi.RichText, blocks ...tgapi.InputRichBlock) tgapi.InputRichBlockDetails {
return tgapi.InputRichBlockDetails{Type: tgapi.InputRichTypeDetails, Summary: sum, Blocks: blocks, IsOpen: true}
}
// Map creates a map block centered on loc.
//
// Zoom accepts 0-24; width and height accept 0-10000 subject to Telegram's
// total-size and aspect-ratio restrictions.
//
// Since: Bot API 10.2
func Map(loc tgapi.Location, zoom uint8, width, height uint16) tgapi.InputRichBlockMap {
return tgapi.InputRichBlockMap{Type: tgapi.InputRichTypeMap, Location: loc, Zoom: zoom, Width: width, Height: height}
}
// MapWithCaption creates a map block with a caption.
//
// Since: Bot API 10.2
func MapWithCaption(loc tgapi.Location, zoom uint8, width, height uint16, caption tgapi.RichBlockCaption) tgapi.InputRichBlockMap {
return tgapi.InputRichBlockMap{Type: tgapi.InputRichTypeMap, Location: loc, Zoom: zoom, Width: width, Height: height, Caption: &caption}
}
// Animation creates an animation block without a caption.
//
// Since: Bot API 10.2
func Animation(animation tgapi.InputMedia) tgapi.InputRichBlockAnimation {
animation.Type = tgapi.InputMediaTypeAnimation
return tgapi.InputRichBlockAnimation{Type: tgapi.InputRichTypeAnimation, Animation: animation}
}
// AnimationWithCaption creates an animation block with a caption.
//
// Since: Bot API 10.2
func AnimationWithCaption(animation tgapi.InputMedia, caption tgapi.RichBlockCaption) tgapi.InputRichBlockAnimation {
block := Animation(animation)
block.Caption = &caption
return block
}
// Audio creates a music-file block without a caption.
//
// Since: Bot API 10.2
func Audio(audio tgapi.InputMedia) tgapi.InputRichBlockAudio {
audio.Type = tgapi.InputMediaTypeAudio
return tgapi.InputRichBlockAudio{Type: tgapi.InputRichTypeAudio, Audio: audio}
}
// AudioWithCaption creates a music-file block with a caption.
//
// Since: Bot API 10.2
func AudioWithCaption(audio tgapi.InputMedia, caption tgapi.RichBlockCaption) tgapi.InputRichBlockAudio {
block := Audio(audio)
block.Caption = &caption
return block
}
// Photo creates a photo block without a caption.
//
// Since: Bot API 10.2
func Photo(photo tgapi.InputMedia) tgapi.InputRichBlockPhoto {
photo.Type = tgapi.InputMediaTypePhoto
return tgapi.InputRichBlockPhoto{Type: tgapi.InputRichTypePhoto, Photo: photo}
}
// PhotoWithCaption creates a photo block with a caption.
//
// Since: Bot API 10.2
func PhotoWithCaption(photo tgapi.InputMedia, caption tgapi.RichBlockCaption) tgapi.InputRichBlockPhoto {
block := Photo(photo)
block.Caption = &caption
return block
}
// Video creates a video block without a caption.
//
// Since: Bot API 10.2
func Video(video tgapi.InputMedia) tgapi.InputRichBlockVideo {
video.Type = tgapi.InputMediaTypeVideo
return tgapi.InputRichBlockVideo{Type: tgapi.InputRichTypeVideo, Video: video}
}
// VideoWithCaption creates a video block with a caption.
//
// Since: Bot API 10.2
func VideoWithCaption(video tgapi.InputMedia, caption tgapi.RichBlockCaption) tgapi.InputRichBlockVideo {
block := Video(video)
block.Caption = &caption
return block
}
// VoiceNote creates a voice-note block without a caption.
//
// Since: Bot API 10.2
func VoiceNote(voiceNote tgapi.InputMedia) tgapi.InputRichBlockVoiceNote {
voiceNote.Type = tgapi.InputMediaTypeVoiceNote
return tgapi.InputRichBlockVoiceNote{Type: tgapi.InputRichTypeVoiceNote, VoiceNote: voiceNote}
}
// VoiceNoteWithCaption creates a voice-note block with a caption.
//
// Since: Bot API 10.2
func VoiceNoteWithCaption(voiceNote tgapi.InputMedia, caption tgapi.RichBlockCaption) tgapi.InputRichBlockVoiceNote {
block := VoiceNote(voiceNote)
block.Caption = &caption
return block
}
// Thinking creates a draft-only thinking placeholder block.
//
// Since: Bot API 10.2
func Thinking(text tgapi.RichText) tgapi.InputRichBlockThinking {
return tgapi.InputRichBlockThinking{Type: tgapi.InputRichTypeThinking, Text: text}
}