func Parse()

in cqlprotodoc/spec/spec.go [71:165]


func Parse(data string) (Document, error) {
	lines := strings.Split(data, "\n")
	var license strings.Builder
	var doc Document
	l := 0
	// license
	for l < len(lines) {
		m := commentRegexp.FindStringSubmatch(lines[l])
		if len(m) != 2 {
			break
		}
		license.WriteString(m[1])
		license.WriteString("\n")
		l++
	}
	doc.License = parseBody(strings.Trim(license.String(), "\n "))
	// empty lines
	for l < len(lines) && emptyRegexp.MatchString(lines[l]) {
		l++
	}
	// title
	if l >= len(lines) {
		return Document{}, fmt.Errorf("missing title")
	}
	m := titleRegexp.FindStringSubmatch(lines[l])
	if len(m) != 2 {
		return Document{}, fmt.Errorf("line %d: title expected on line", l)
	}
	doc.Title = m[1]
	l++
	// empty lines
	for l < len(lines) && emptyRegexp.MatchString(lines[l]) {
		l++
	}
	// table of contents header
	if lines[l] != "Table of Contents" {
		return Document{}, fmt.Errorf("line %d: expected table of contents", l)
	}
	l++
	// empty lines
	for l < len(lines) && emptyRegexp.MatchString(lines[l]) {
		l++
	}
	// toc entries
	for l < len(lines) {
		if emptyRegexp.MatchString(lines[l]) {
			// end of toc
			break
		}
		mh := headingRegexp.FindStringSubmatch(lines[l])
		if len(mh) != 4 {
			return Document{}, fmt.Errorf("line %d: expected toc entry", l)
		}
		doc.TOC = append(doc.TOC, TOCEntry{
			Number: mh[mhNumber],
			Title:  mh[mhTitle],
		})
		l++
	}
	// empty lines
	for l < len(lines) && emptyRegexp.MatchString(lines[l]) {
		l++
	}
	// content
	tocIdx := 0
	var section Section
	var body []string

	for l < len(lines) {
		var sectionStart bool
		var newSection Section
		sectionStart, tocIdx, newSection = checkSectionStart(doc.TOC, tocIdx, lines[l])
		if sectionStart {
			section.Body = parseBody(strings.Join(body, "\n"))
			doc.Sections = append(doc.Sections, section)
			section = newSection
			body = nil
			l++
			// Eat empty lines
			for l < len(lines) && emptyRegexp.MatchString(lines[l]) {
				l++
			}
			continue
		}
		body = append(body, lines[l])
		l++
	}

	if len(body) > 0 || !section.Empty() {
		section.Body = parseBody(strings.Join(body, "\n"))
		doc.Sections = append(doc.Sections, section)
	}

	return doc, nil
}