github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/model/note/custom/panel.go (about)

     1  package custom
     2  
     3  import (
     4  	"github.com/yuin/goldmark/ast"
     5  	"github.com/yuin/goldmark/parser"
     6  	"github.com/yuin/goldmark/text"
     7  	"github.com/yuin/goldmark/util"
     8  )
     9  
    10  // A Panel struct represents a panel in atlaskit.
    11  type Panel struct {
    12  	ast.BaseBlock
    13  	PanelType string
    14  }
    15  
    16  // Dump implements Node.Dump.
    17  func (n *Panel) Dump(source []byte, level int) {
    18  	ast.DumpHelper(n, source, level, nil, nil)
    19  }
    20  
    21  // KindPanel is a NodeKind of the Panel node.
    22  var KindPanel = ast.NewNodeKind("Panel")
    23  
    24  // Kind implements Node.Kind.
    25  func (n *Panel) Kind() ast.NodeKind {
    26  	return KindPanel
    27  }
    28  
    29  // NewPanel returns a new Panel node.
    30  func NewPanel(panelType string) *Panel {
    31  	return &Panel{
    32  		BaseBlock: ast.BaseBlock{},
    33  		PanelType: panelType,
    34  	}
    35  }
    36  
    37  type panelParser struct{}
    38  
    39  var defaultPanelParser = &panelParser{}
    40  
    41  // NewPanelParser returns a new BlockParser that
    42  // parses panels.
    43  func NewPanelParser() parser.BlockParser {
    44  	return defaultPanelParser
    45  }
    46  
    47  func (b *panelParser) Trigger() []byte {
    48  	return []byte{':'}
    49  }
    50  
    51  func (b *panelParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State) {
    52  	line, _ := reader.PeekLine()
    53  	w, pos := util.IndentWidth(line, reader.LineOffset())
    54  	if w > 3 || pos >= len(line) || line[pos] != ':' {
    55  		return nil, parser.NoChildren
    56  	}
    57  	pos++
    58  	for start := pos; pos-start < 10; pos++ {
    59  		if pos >= len(line) || line[pos] == '\n' {
    60  			break
    61  		}
    62  		if line[pos] == ':' {
    63  			panelType := string(line[start:pos])
    64  			pos++
    65  			if pos >= len(line) || line[pos] != ' ' {
    66  				break
    67  			}
    68  			switch panelType {
    69  			case "info", "note", "success", "warning", "error":
    70  				reader.Advance(pos)
    71  				return NewPanel(panelType), parser.HasChildren
    72  			}
    73  			break
    74  		}
    75  	}
    76  	return nil, parser.NoChildren
    77  }
    78  
    79  func (b *panelParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
    80  	line, segment := reader.PeekLine()
    81  	if util.IsBlank(line) {
    82  		return parser.Close
    83  	}
    84  	reader.Advance(segment.Len() - 1)
    85  	return parser.Continue | parser.HasChildren
    86  }
    87  
    88  func (b *panelParser) Close(node ast.Node, reader text.Reader, pc parser.Context) {
    89  	// nothing to do
    90  }
    91  
    92  func (b *panelParser) CanInterruptParagraph() bool {
    93  	return false
    94  }
    95  
    96  func (b *panelParser) CanAcceptIndentedLine() bool {
    97  	return false
    98  }