1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build go1.16
6// +build go1.16
7
8package doc
9
10import (
11	"strings"
12	"unicode"
13)
14
15// firstSentenceLen returns the length of the first sentence in s.
16// The sentence ends after the first period followed by space and
17// not preceded by exactly one uppercase letter.
18//
19func firstSentenceLen(s string) int {
20	var ppp, pp, p rune
21	for i, q := range s {
22		if q == '\n' || q == '\r' || q == '\t' {
23			q = ' '
24		}
25		if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
26			return i
27		}
28		if p == '。' || p == '.' {
29			return i
30		}
31		ppp, pp, p = pp, p, q
32	}
33	return len(s)
34}
35
36const (
37	keepNL = 1 << iota
38)
39
40// clean replaces each sequence of space, \n, \r, or \t characters
41// with a single space and removes any trailing and leading spaces.
42// If the keepNL flag is set, newline characters are passed through
43// instead of being change to spaces.
44func clean(s string, flags int) string {
45	var b []byte
46	p := byte(' ')
47	for i := 0; i < len(s); i++ {
48		q := s[i]
49		if (flags&keepNL) == 0 && q == '\n' || q == '\r' || q == '\t' {
50			q = ' '
51		}
52		if q != ' ' || p != ' ' {
53			b = append(b, q)
54			p = q
55		}
56	}
57	// remove trailing blank, if any
58	if n := len(b); n > 0 && p == ' ' {
59		b = b[0 : n-1]
60	}
61	return string(b)
62}
63
64// Synopsis returns a cleaned version of the first sentence in s.
65// That sentence ends after the first period followed by space and
66// not preceded by exactly one uppercase letter. The result string
67// has no \n, \r, or \t characters and uses only single spaces between
68// words. If s starts with any of the IllegalPrefixes, the result
69// is the empty string.
70//
71func Synopsis(s string) string {
72	s = clean(s[0:firstSentenceLen(s)], 0)
73	for _, prefix := range IllegalPrefixes {
74		if strings.HasPrefix(strings.ToLower(s), prefix) {
75			return ""
76		}
77	}
78	s = convertQuotes(s)
79	return s
80}
81
82var IllegalPrefixes = []string{
83	"copyright",
84	"all rights",
85	"author",
86}
87