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