...

Source file src/github.com/yuin/goldmark/parser/code_span.go

Documentation: github.com/yuin/goldmark/parser

     1  package parser
     2  
     3  import (
     4  	"github.com/yuin/goldmark/ast"
     5  	"github.com/yuin/goldmark/text"
     6  )
     7  
     8  type codeSpanParser struct {
     9  }
    10  
    11  var defaultCodeSpanParser = &codeSpanParser{}
    12  
    13  // NewCodeSpanParser return a new InlineParser that parses inline codes
    14  // surrounded by '`' .
    15  func NewCodeSpanParser() InlineParser {
    16  	return defaultCodeSpanParser
    17  }
    18  
    19  func (s *codeSpanParser) Trigger() []byte {
    20  	return []byte{'`'}
    21  }
    22  
    23  func (s *codeSpanParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node {
    24  	line, startSegment := block.PeekLine()
    25  	opener := 0
    26  	for ; opener < len(line) && line[opener] == '`'; opener++ {
    27  	}
    28  	block.Advance(opener)
    29  	l, pos := block.Position()
    30  	node := ast.NewCodeSpan()
    31  	for {
    32  		line, segment := block.PeekLine()
    33  		if line == nil {
    34  			block.SetPosition(l, pos)
    35  			return ast.NewTextSegment(startSegment.WithStop(startSegment.Start + opener))
    36  		}
    37  		for i := 0; i < len(line); i++ {
    38  			c := line[i]
    39  			if c == '`' {
    40  				oldi := i
    41  				for ; i < len(line) && line[i] == '`'; i++ {
    42  				}
    43  				closure := i - oldi
    44  				if closure == opener && (i >= len(line) || line[i] != '`') {
    45  					segment = segment.WithStop(segment.Start + i - closure)
    46  					if !segment.IsEmpty() {
    47  						node.AppendChild(node, ast.NewRawTextSegment(segment))
    48  					}
    49  					block.Advance(i)
    50  					goto end
    51  				}
    52  			}
    53  		}
    54  		node.AppendChild(node, ast.NewRawTextSegment(segment))
    55  		block.AdvanceLine()
    56  	}
    57  end:
    58  	if !node.IsBlank(block.Source()) {
    59  		// trim first halfspace and last halfspace
    60  		segment := node.FirstChild().(*ast.Text).Segment
    61  		shouldTrimmed := true
    62  		if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Start])) {
    63  			shouldTrimmed = false
    64  		}
    65  		segment = node.LastChild().(*ast.Text).Segment
    66  		if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Stop-1])) {
    67  			shouldTrimmed = false
    68  		}
    69  		if shouldTrimmed {
    70  			t := node.FirstChild().(*ast.Text)
    71  			segment := t.Segment
    72  			t.Segment = segment.WithStart(segment.Start + 1)
    73  			t = node.LastChild().(*ast.Text)
    74  			segment = node.LastChild().(*ast.Text).Segment
    75  			t.Segment = segment.WithStop(segment.Stop - 1)
    76  		}
    77  
    78  	}
    79  	return node
    80  }
    81  
    82  func isSpaceOrNewline(c byte) bool {
    83  	return c == ' ' || c == '\n'
    84  }
    85  

View as plain text