github.com/vnforks/kid@v5.11.1+incompatible/utils/markdown/reference_definition.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package markdown
     5  
     6  type ReferenceDefinition struct {
     7  	RawDestination Range
     8  
     9  	markdown string
    10  	rawLabel string
    11  	rawTitle string
    12  }
    13  
    14  func (d *ReferenceDefinition) Destination() string {
    15  	return Unescape(d.markdown[d.RawDestination.Position:d.RawDestination.End])
    16  }
    17  
    18  func (d *ReferenceDefinition) Label() string {
    19  	return d.rawLabel
    20  }
    21  
    22  func (d *ReferenceDefinition) Title() string {
    23  	return Unescape(d.rawTitle)
    24  }
    25  
    26  func parseReferenceDefinition(markdown string, ranges []Range) (*ReferenceDefinition, []Range) {
    27  	raw := ""
    28  	for _, r := range ranges {
    29  		raw += markdown[r.Position:r.End]
    30  	}
    31  
    32  	label, next, ok := parseLinkLabel(raw, 0)
    33  	if !ok {
    34  		return nil, nil
    35  	}
    36  	position := next
    37  
    38  	if position >= len(raw) || raw[position] != ':' {
    39  		return nil, nil
    40  	}
    41  	position++
    42  
    43  	destination, next, ok := parseLinkDestination(raw, nextNonWhitespace(raw, position))
    44  	if !ok {
    45  		return nil, nil
    46  	}
    47  	position = next
    48  
    49  	absoluteDestination := relativeToAbsolutePosition(ranges, destination.Position)
    50  	ret := &ReferenceDefinition{
    51  		RawDestination: Range{absoluteDestination, absoluteDestination + destination.End - destination.Position},
    52  		markdown:       markdown,
    53  		rawLabel:       raw[label.Position:label.End],
    54  	}
    55  
    56  	if position < len(raw) && isWhitespaceByte(raw[position]) {
    57  		title, next, ok := parseLinkTitle(raw, nextNonWhitespace(raw, position))
    58  		if !ok {
    59  			if nextLine, skippedNonWhitespace := nextLine(raw, position); !skippedNonWhitespace {
    60  				return ret, trimBytesFromRanges(ranges, nextLine)
    61  			}
    62  			return nil, nil
    63  		}
    64  		if nextLine, skippedNonWhitespace := nextLine(raw, next); !skippedNonWhitespace {
    65  			ret.rawTitle = raw[title.Position:title.End]
    66  			return ret, trimBytesFromRanges(ranges, nextLine)
    67  		}
    68  	}
    69  
    70  	if nextLine, skippedNonWhitespace := nextLine(raw, position); !skippedNonWhitespace {
    71  		return ret, trimBytesFromRanges(ranges, nextLine)
    72  	}
    73  
    74  	return nil, nil
    75  }