diff --git a/present/doc.go b/present/doc.go index 2256f31082..804ec847b3 100644 --- a/present/doc.go +++ b/present/doc.go @@ -77,14 +77,22 @@ Fonts: Within the input for plain text or lists, text bracketed by font markers will be presented in italic, bold, or program font. Marker characters are _ (italic), * (bold) and ` (program font). -Unmatched markers appear as plain text. -Within marked text, a single marker character becomes a space -and a doubled single marker quotes the marker character. +An opening marker must be preceded by a space or punctuation +character or else be at start of a line; similarly, a closing +marker must be followed by a space or punctuation character or +else be at the end of a line. Unmatched markers appear as plain text. +There must be no spaces between markers. Within marked text, +a single marker character becomes a space and a doubled single +marker quotes the marker character. + +at the beginning of a line or +else be preceded by a space or punctuation; similarly a closing +marker must be at the end of the lineo _italic_ *bold* `program` - _this_is_all_italic_ + Markup—_especially_italic_text_—can easily be overused. _Why_use_scoped__ptr_? Use plain ***ptr* instead. Inline links: diff --git a/present/style.go b/present/style.go index 1cd240de72..a6d8d39cc9 100644 --- a/present/style.go +++ b/present/style.go @@ -52,16 +52,16 @@ Word: words[w] = link continue Word } - const punctuation = `.,;:()!?—–'"` const marker = "_*`" // Initial punctuation is OK but must be peeled off. first := strings.IndexAny(word, marker) if first == -1 { continue Word } - // Is the marker prefixed only by punctuation? - for _, r := range word[:first] { - if !strings.ContainsRune(punctuation, r) { + // Opening marker must be at the beginning of the token or else preceded by punctuation. + if first != 0 { + r, _ := utf8.DecodeLastRuneInString(word[:first]) + if !unicode.IsPunct(r) { continue Word } } @@ -81,17 +81,18 @@ Word: open += "" close = "" } - // Terminal punctuation is OK but must be peeled off. + // Closing marker must be at the end of the token or else followed by punctuation. last := strings.LastIndex(word, word[:1]) if last == 0 { continue Word } - head, tail := word[:last+1], word[last+1:] - for _, r := range tail { - if !strings.ContainsRune(punctuation, r) { + if last+1 != len(word) { + r, _ := utf8.DecodeRuneInString(word[last+1:]) + if !unicode.IsPunct(r) { continue Word } } + head, tail := word[:last+1], word[last+1:] b.Reset() b.WriteString(open) var wid int diff --git a/present/style_test.go b/present/style_test.go index d04db72d25..cef5a62f5c 100644 --- a/present/style_test.go +++ b/present/style_test.go @@ -72,6 +72,14 @@ func TestFont(t *testing.T) { `Visit golang.org now`}, {"my talk ([[http://talks.golang.org/][slides here]])", `my talk (slides here)`}, + {"Markup—_especially_italic_text_—can easily be overused.", + `Markup—especially italic text—can easily be overused.`}, + {"`go`get`'s codebase", // ascii U+0027 ' before s + `go get's codebase`}, + {"`go`get`’s codebase", // unicode right single quote U+2019 ’ before s + `go get’s codebase`}, + {"a_variable_name", + `a_variable_name`}, } for _, test := range tests { out := font(test.in)