View definition

func FormatSelections

Defined in


FormatSelections takes a text and writes it to w using link and segment writers lw and sw as follows: lw is invoked for consecutive segment starts and ends as specified through the links selection, and sw is invoked for consecutive segments of text overlapped by the same selections as specified by selections. The link writer lw may be nil, in which case the links Selection is ignored.

FormatSelections is referenced in 1 repository


func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection, sw SegmentWriter, selections ...Selection) {
	// If we have a link writer, make the links
	// selection the last entry in selections
	if lw != nil {
		selections = append(selections, links)

	// compute the sequence of consecutive segment changes
	changes := newMerger(selections)

	// The i'th bit in bitset indicates that the text
	// at the current offset is covered by selections[i].
	bitset := 0
	lastOffs := 0

	// Text segments are written in a delayed fashion
	// such that consecutive segments belonging to the
	// same selection can be combined (peephole optimization).
	// last describes the last segment which has not yet been written.
	var last struct {
		begin, end int // valid if begin < end
		bitset     int

	// flush writes the last delayed text segment
	flush := func() {
		if last.begin < last.end {
			sw(w, text[last.begin:last.end], last.bitset)
		last.begin = last.end // invalidate last

	// segment runs the segment [lastOffs, end) with the selection
	// indicated by bitset through the segment peephole optimizer.
	segment := func(end int) {
		if lastOffs < end { // ignore empty segments
			if last.end != lastOffs || last.bitset != bitset {
				// the last segment is not adjacent to or
				// differs from the new one
				// start a new segment
				last.begin = lastOffs
			last.end = end
			last.bitset = bitset

	for {
		// get the next segment change
		index, offs, start :=
		if index < 0 || offs > len(text) {
			// no more segment changes or the next change
			// is past the end of the text - we're done
		// determine the kind of segment change
		if lw != nil && index == len(selections)-1 {
			// we have a link segment change (see start of this function):
			// format the previous selection segment, write the
			// link tag and start a new selection segment
			lastOffs = offs
			lw(w, offs, start)
		} else {
			// we have a selection change:
			// format the previous selection segment, determine
			// the new selection bitset and start a new segment
			lastOffs = offs
			mask := 1 << uint(index)
			if start {
				bitset |= mask
			} else {
				bitset &^= mask