github.com/bitcubate/cryptojournal@v1.2.5-0.20171102134152-f578b3d788ab/src/lib/text/text.go (about) 1 // Package text performs text manipulation on html strings 2 // it is used by stories and comments 3 package text 4 5 import ( 6 "regexp" 7 "strings" 8 ) 9 10 var ( 11 // Trailing defines optional characters allowed after a url or username 12 // this excludes some valid urls but urls are not expected to end 13 // in these characters 14 trailing = `([\s!?.,]?)` 15 16 // Search for links prefaced by word separators (\s\n\.) 17 // i.e. not already in anchors, and replace with auto-link 18 // `\s(https?://.*)[\s.!?]` 19 // match urls at start of text or with space before only 20 urlRx = regexp.MustCompile(`(\A|[\s]+)(https?://[^\s><]*)` + trailing) 21 22 // Search for \s@name in text and replace with links to username search 23 // requires an endpoint that redirects /u/kenny to /users/1 etc. 24 userRx = regexp.MustCompile(`(\A|[\s]+)@([^\s!?.,<>]*)` + trailing) 25 26 // Search for trailing <p>\s for ConvertNewlines 27 trailingPara = regexp.MustCompile(`<p>\s*\z`) 28 ) 29 30 // ConvertNewlines converts \n to paragraph tags 31 // if the text already contains paragraph tags, return unaltered 32 func ConvertNewlines(s string) string { 33 if strings.Contains(s, "<p>") { 34 return s 35 } 36 37 // Start with para 38 s = "<p>" + s 39 // Replace newlines with paras 40 s = strings.Replace(s, "\n", "</p><p>", -1) 41 // Remove trailing para added in step above 42 s = string(trailingPara.ReplaceAll([]byte(s), []byte(""))) 43 return s 44 } 45 46 // ConvertLinks returns the text with various transformations applied - 47 // bare links are turned into anchor tags, and @refs are turned into user links. 48 // this is somewhat fragile, better to parse the html 49 func ConvertLinks(s string) string { 50 bytes := []byte(s) 51 // Replace bare links with active links 52 bytes = urlRx.ReplaceAll(bytes, []byte(`$1<a href="$2">$2</a>$3`)) 53 // Replace usernames with links 54 bytes = userRx.ReplaceAll(bytes, []byte(`$1<a href="/u/$2">@$2</a>$3`)) 55 return string(bytes) 56 }