github.com/anthonyme00/gomarkdoc@v1.0.0/lang/block.go (about) 1 package lang 2 3 import ( 4 "go/doc/comment" 5 "strings" 6 ) 7 8 type ( 9 // Block defines a single block element (e.g. paragraph, code block) in the 10 // documentation for a symbol or package. 11 Block struct { 12 cfg *Config 13 kind BlockKind 14 spans []*Span 15 list *List 16 inline bool 17 } 18 19 // BlockKind identifies the type of block element represented by the 20 // corresponding Block. 21 BlockKind string 22 ) 23 24 const ( 25 // ParagraphBlock defines a block that represents a paragraph of text. 26 ParagraphBlock BlockKind = "paragraph" 27 28 // CodeBlock defines a block that represents a section of code. 29 CodeBlock BlockKind = "code" 30 31 // HeaderBlock defines a block that represents a section header. 32 HeaderBlock BlockKind = "header" 33 34 // ListBlock defines a block that represents an ordered or unordered list. 35 ListBlock BlockKind = "list" 36 ) 37 38 // NewBlock creates a new block element of the provided kind and with the given 39 // text spans and a flag indicating whether this block is part of an inline 40 // element. 41 func NewBlock(cfg *Config, kind BlockKind, spans []*Span, inline bool) *Block { 42 return &Block{cfg, kind, spans, nil, inline} 43 } 44 45 // NewListBlock creates a new list block element and with the given list 46 // definition and a flag indicating whether this block is part of an inline 47 // element. 48 func NewListBlock(cfg *Config, list *List, inline bool) *Block { 49 return &Block{cfg, ListBlock, nil, list, inline} 50 } 51 52 // Level provides the default level that a block of kind HeaderBlock will render 53 // at in the output. The level is not used for other block types. 54 func (b *Block) Level() int { 55 return b.cfg.Level 56 } 57 58 // Kind provides the kind of data that this block's text should be interpreted 59 // as. 60 func (b *Block) Kind() BlockKind { 61 return b.kind 62 } 63 64 // Spans provides the raw text of the block's contents as a set of text spans. 65 // The text is pre-scrubbed and sanitized as determined by the block's Kind(), 66 // but it is not wrapped in any special constructs for rendering purposes (such 67 // as markdown code blocks). 68 func (b *Block) Spans() []*Span { 69 return b.spans 70 } 71 72 // List provides the list contents for a list block. Only relevant for blocks of 73 // type ListBlock. 74 func (b *Block) List() *List { 75 return b.list 76 } 77 78 // Inline indicates whether the block is part of an inline element, such as a 79 // list item. 80 func (b *Block) Inline() bool { 81 return b.inline 82 } 83 84 // ParseBlocks produces a set of blocks from the corresponding comment blocks. 85 // It also takes a flag indicating whether the blocks are part of an inline 86 // element such as a list item. 87 func ParseBlocks(cfg *Config, blocks []comment.Block, inline bool) []*Block { 88 res := make([]*Block, len(blocks)) 89 for i, b := range blocks { 90 switch v := b.(type) { 91 case *comment.Code: 92 res[i] = NewBlock( 93 cfg.Inc(0), 94 CodeBlock, 95 []*Span{NewSpan(cfg.Inc(0), RawTextSpan, v.Text, "")}, 96 inline, 97 ) 98 case *comment.Heading: 99 var b strings.Builder 100 printText(&b, v.Text...) 101 res[i] = NewBlock(cfg.Inc(0), HeaderBlock, ParseSpans(cfg, v.Text), inline) 102 case *comment.List: 103 list := NewList(cfg.Inc(0), v) 104 res[i] = NewListBlock(cfg.Inc(0), list, inline) 105 case *comment.Paragraph: 106 res[i] = NewBlock(cfg.Inc(0), ParagraphBlock, ParseSpans(cfg, v.Text), inline) 107 } 108 } 109 110 return res 111 }