github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/model/note/custom/table.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  type TableType int
    11  
    12  // A Table struct represents a table in atlaskit.
    13  type Table struct {
    14  	ast.BaseBlock
    15  }
    16  
    17  // Dump implements Node.Dump.
    18  func (n *Table) Dump(source []byte, level int) {
    19  	ast.DumpHelper(n, source, level, nil, nil)
    20  }
    21  
    22  // KindTable is a NodeKind of the Table node.
    23  var KindTable = ast.NewNodeKind("Table")
    24  
    25  // Kind implements Node.Kind.
    26  func (n *Table) Kind() ast.NodeKind {
    27  	return KindTable
    28  }
    29  
    30  // NewTable returns a new Table node.
    31  func NewTable() *Table {
    32  	return &Table{
    33  		BaseBlock: ast.BaseBlock{},
    34  	}
    35  }
    36  
    37  type tableParser struct{}
    38  
    39  var defaultTableParser = &tableParser{}
    40  
    41  // NewTableParser returns a new BlockParser that parses tables.
    42  // This parser must take precedence over the parser.ThematicBreakParser.
    43  func NewTableParser() parser.BlockParser {
    44  	return defaultTableParser
    45  }
    46  
    47  func (b *tableParser) Trigger() []byte {
    48  	return []byte{'_'}
    49  }
    50  
    51  func (b *tableParser) 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 {
    55  		return nil, parser.NoChildren
    56  	}
    57  	count := 0
    58  	for i := pos; i < len(line); i++ {
    59  		c := line[i]
    60  		if c == '{' {
    61  			break
    62  		}
    63  		if c != '_' {
    64  			count = 0
    65  			break
    66  		}
    67  		count++
    68  	}
    69  	if count < 10 {
    70  		return nil, parser.NoChildren
    71  	}
    72  	reader.Advance(count)
    73  	node := NewTable()
    74  	if attrs, ok := parser.ParseAttributes(reader); ok {
    75  		for _, attr := range attrs {
    76  			if value, ok := attr.Value.([]byte); ok {
    77  				node.SetAttribute(attr.Name, string(value))
    78  			} else {
    79  				node.SetAttribute(attr.Name, attr.Value)
    80  			}
    81  		}
    82  	}
    83  	return node, parser.HasChildren
    84  }
    85  
    86  func (b *tableParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
    87  	return parser.Close
    88  }
    89  
    90  func (b *tableParser) Close(node ast.Node, reader text.Reader, pc parser.Context) {
    91  	// nothing to do
    92  }
    93  
    94  func (b *tableParser) CanInterruptParagraph() bool {
    95  	return true
    96  }
    97  
    98  func (b *tableParser) CanAcceptIndentedLine() bool {
    99  	return false
   100  }