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  }