From c3b7691431739902831f5a43610314737996ec36 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Wed, 16 Feb 2022 22:27:33 -0600 Subject: [PATCH 1/5] add failing typographer tests --- extension/_test/typographer.txt | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/extension/_test/typographer.txt b/extension/_test/typographer.txt index ef90bce..7534d83 100644 --- a/extension/_test/typographer.txt +++ b/extension/_test/typographer.txt @@ -64,3 +64,80 @@ reported "issue 1 (IE-only)", "issue 2", 'issue3 (FF-only)', 'issue4' //- - - - - - - - -//

“Monitor 21"” and “Monitor”"

//= = = = = = = = = = = = = = = = = = = = = = = =// + +9: Closing quotation marks within italics +//- - - - - - - - -// +*"At first, things were not clear."* +//- - - - - - - - -// +“At first, things were not clear.” +//= = = = = = = = = = = = = = = = = = = = = = = =// + +10: Closing quotation marks within boldfacing +//- - - - - - - - -// +**"At first, things were not clear."** +//- - - - - - - - -// +“At first, things were not clear.” +//= = = = = = = = = = = = = = = = = = = = = = = =// + +11: Closing quotation marks within boldfacing and italics +//- - - - - - - - -// +***"At first, things were not clear."*** +//- - - - - - - - -// +“At first, things were not clear.” +//= = = = = = = = = = = = = = = = = = = = = = = =// + +12: Closing quotation marks within boldfacing and italics +//- - - - - - - - -// +***"At first, things were not clear."*** +//- - - - - - - - -// +“At first, things were not clear.” +//= = = = = = = = = = = = = = = = = = = = = = = =// + +13: Plural possessives +//- - - - - - - - -// +John's dog is named Sam. The Smiths' dog is named Rover. +//- - - - - - - - -// +John’s dog is named Sam. The Smiths’ dog is named Rover. +//= = = = = = = = = = = = = = = = = = = = = = = =// + +14: Links within quotation marks and parenthetical phrases +//- - - - - - - - -// +This is not difficult (see "[Introduction to Hugo Templating](https://gohugo.io/templates/introduction/)"). +//- - - - - - - - -// +This is not difficult (see “[Introduction to Hugo Templating](https://gohugo.io/templates/introduction/)”). +//= = = = = = = = = = = = = = = = = = = = = = = =// + +15: Quotation marks within links +//- - - - - - - - -// +Apple's early Cairo font gave us ["moof" and the "dogcow."](https://www.macworld.com/article/2926184/we-miss-you-clarus-the-dogcow.html) +//- - - - - - - - -// +Apple’s early Cairo font gave us “moof” and the “dogcow.” +//= = = = = = = = = = = = = = = = = = = = = = = =// + +16: Single closing quotation marks with slang/informalities +//- - - - - - - - -// +"I'm not doin' that," Bill said with emphasis. +//- - - - - - - - -// +“I’m not doin’ that,” Bill said with emphasis. +//= = = = = = = = = = = = = = = = = = = = = = = =// + +17: Closing single quotation marks in quotations-within-quotations +//- - - - - - - - -// +Janet said, "When everything is 'breaking news,' nothing is 'breaking news.'" +//- - - - - - - - -// +Janet said, “When everything is ‘breaking news,’ nothing is ‘breaking news.’” +//= = = = = = = = = = = = = = = = = = = = = = = =// + +18: Opening single quotation marks for abbreviations +//- - - - - - - - -// +We're talking about the internet --- 'net for short. +//- - - - - - - - -// +We’re talking about the internet — ’net for short. +//= = = = = = = = = = = = = = = = = = = = = = = =// + +19: Quotation marks next to footnotes +//- - - - - - - - -// +People ask, "Why can't you just change the format?"[^formatChgNote] +//- - - - - - - - -// +People ask, “Why can’t you just change the format?”1 +//= = = = = = = = = = = = = = = = = = = = = = = =// From 7b616a4c803bb3c8bb3f9d7540e8123c1d5a87f6 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 17 Feb 2022 09:41:29 -0600 Subject: [PATCH 2/5] fix typographer single quote edge cases --- extension/_test/typographer.txt | 26 ++++++++++---------------- extension/typographer.go | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/extension/_test/typographer.txt b/extension/_test/typographer.txt index 7534d83..af6c1cb 100644 --- a/extension/_test/typographer.txt +++ b/extension/_test/typographer.txt @@ -69,75 +69,69 @@ reported "issue 1 (IE-only)", "issue 2", 'issue3 (FF-only)', 'issue4' //- - - - - - - - -// *"At first, things were not clear."* //- - - - - - - - -// -“At first, things were not clear.” +

“At first, things were not clear.”

//= = = = = = = = = = = = = = = = = = = = = = = =// 10: Closing quotation marks within boldfacing //- - - - - - - - -// **"At first, things were not clear."** //- - - - - - - - -// -“At first, things were not clear.” +

“At first, things were not clear.”

//= = = = = = = = = = = = = = = = = = = = = = = =// 11: Closing quotation marks within boldfacing and italics //- - - - - - - - -// ***"At first, things were not clear."*** //- - - - - - - - -// -“At first, things were not clear.” +

“At first, things were not clear.”

//= = = = = = = = = = = = = = = = = = = = = = = =// 12: Closing quotation marks within boldfacing and italics //- - - - - - - - -// ***"At first, things were not clear."*** //- - - - - - - - -// -“At first, things were not clear.” +

“At first, things were not clear.”

//= = = = = = = = = = = = = = = = = = = = = = = =// 13: Plural possessives //- - - - - - - - -// John's dog is named Sam. The Smiths' dog is named Rover. //- - - - - - - - -// -John’s dog is named Sam. The Smiths’ dog is named Rover. +

John’s dog is named Sam. The Smiths’ dog is named Rover.

//= = = = = = = = = = = = = = = = = = = = = = = =// 14: Links within quotation marks and parenthetical phrases //- - - - - - - - -// This is not difficult (see "[Introduction to Hugo Templating](https://gohugo.io/templates/introduction/)"). //- - - - - - - - -// -This is not difficult (see “[Introduction to Hugo Templating](https://gohugo.io/templates/introduction/)”). +

This is not difficult (see “Introduction to Hugo Templating”).

//= = = = = = = = = = = = = = = = = = = = = = = =// 15: Quotation marks within links //- - - - - - - - -// Apple's early Cairo font gave us ["moof" and the "dogcow."](https://www.macworld.com/article/2926184/we-miss-you-clarus-the-dogcow.html) //- - - - - - - - -// -Apple’s early Cairo font gave us “moof” and the “dogcow.” +

Apple’s early Cairo font gave us “moof” and the “dogcow.”

//= = = = = = = = = = = = = = = = = = = = = = = =// 16: Single closing quotation marks with slang/informalities //- - - - - - - - -// "I'm not doin' that," Bill said with emphasis. //- - - - - - - - -// -“I’m not doin’ that,” Bill said with emphasis. +

“I’m not doin’ that,” Bill said with emphasis.

//= = = = = = = = = = = = = = = = = = = = = = = =// 17: Closing single quotation marks in quotations-within-quotations //- - - - - - - - -// Janet said, "When everything is 'breaking news,' nothing is 'breaking news.'" //- - - - - - - - -// -Janet said, “When everything is ‘breaking news,’ nothing is ‘breaking news.’” +

Janet said, “When everything is ‘breaking news,’ nothing is ‘breaking news.’”

//= = = = = = = = = = = = = = = = = = = = = = = =// 18: Opening single quotation marks for abbreviations //- - - - - - - - -// We're talking about the internet --- 'net for short. //- - - - - - - - -// -We’re talking about the internet — ’net for short. +

We’re talking about the internet — ’net for short.

//= = = = = = = = = = = = = = = = = = = = = = = =// -19: Quotation marks next to footnotes -//- - - - - - - - -// -People ask, "Why can't you just change the format?"[^formatChgNote] -//- - - - - - - - -// -People ask, “Why can’t you just change the format?”1 -//= = = = = = = = = = = = = = = = = = = = = = = =// diff --git a/extension/typographer.go b/extension/typographer.go index 2c34730..4a57ba4 100644 --- a/extension/typographer.go +++ b/extension/typographer.go @@ -160,7 +160,7 @@ func NewTypographerParser(opts ...TypographerOption) parser.InlineParser { } func (s *typographerParser) Trigger() []byte { - return []byte{'\'', '"', '-', '.', '<', '>'} + return []byte{'\'', '"', '-', '.', ',', '<', '>', '*', '['} } func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node { @@ -241,7 +241,7 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser } if s.Substitutions[LeftSingleQuote] != nil && d.CanOpen && !d.CanClose { nt := LeftSingleQuote - // special cases: Alice's, I'm ,Don't, You'd + // special cases: Alice's, I'm, Don't, You'd if len(line) > 1 && (line[1] == 's' || line[1] == 'm' || line[1] == 't' || line[1] == 'd') && (len(line) < 3 || util.IsPunct(line[2]) || util.IsSpace(line[2])) { nt = RightSingleQuote } @@ -258,9 +258,17 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser block.Advance(1) return node } + if s.Substitutions[RightSingleQuote] != nil { + if len(line) > 1 && unicode.IsSpace(util.ToRune(line, 0)) || unicode.IsPunct(util.ToRune(line, 0)) && (len(line) > 2 && !unicode.IsDigit(util.ToRune(line, 1))) { + node := gast.NewString(s.Substitutions[RightSingleQuote]) + node.SetCode(true) + block.Advance(1) + return node + } + } if s.Substitutions[RightSingleQuote] != nil && counter.Single > 0 { isClose := d.CanClose && !d.CanOpen - maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (line[1] == ',' || line[1] == '.' || line[1] == '!' || line[1] == '?') && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) + maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && unicode.IsPunct(util.ToRune(line, 1)) && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) if isClose || maybeClose { node := gast.NewString(s.Substitutions[RightSingleQuote]) node.SetCode(true) @@ -280,7 +288,7 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser } if s.Substitutions[RightDoubleQuote] != nil && counter.Double > 0 { isClose := d.CanClose && !d.CanOpen - maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (line[1] == ',' || line[1] == '.' || line[1] == '!' || line[1] == '?') && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) + maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (unicode.IsPunct(util.ToRune(line, 1))) && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) if isClose || maybeClose { // special case: "Monitor 21"" if len(line) > 1 && line[1] == '"' && unicode.IsDigit(before) { From a6c48071edc9baf120e8edbe4cf713ef1835dbaf Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 17 Feb 2022 10:04:21 -0600 Subject: [PATCH 3/5] fix typographer leading apostrophe for abbreviations --- extension/_test/typographer.txt | 5 ++--- extension/typographer.go | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/extension/_test/typographer.txt b/extension/_test/typographer.txt index af6c1cb..556353c 100644 --- a/extension/_test/typographer.txt +++ b/extension/_test/typographer.txt @@ -130,8 +130,7 @@ Janet said, "When everything is 'breaking news,' nothing is 'breaking news.'" 18: Opening single quotation marks for abbreviations //- - - - - - - - -// -We're talking about the internet --- 'net for short. +We're talking about the internet --- 'net for short. Let's rock 'n roll! //- - - - - - - - -// -

We’re talking about the internet — ’net for short.

+

We’re talking about the internet — ’net for short. Let’s rock ’n roll!

//= = = = = = = = = = = = = = = = = = = = = = = =// - diff --git a/extension/typographer.go b/extension/typographer.go index 4a57ba4..a788228 100644 --- a/extension/typographer.go +++ b/extension/typographer.go @@ -1,6 +1,7 @@ package extension import ( + "fmt" "unicode" "github.com/yuin/goldmark" @@ -230,6 +231,14 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser return node } } + // special cases: 'twas, 'em, 'net + if len(line) > 1 && (unicode.IsPunct(before) || unicode.IsSpace(before)) && (line[1] == 't' || line[1] == 'e' || line[1] == 'n' || line[1] == 'l') { + fmt.Println(string(line)) + node := gast.NewString(s.Substitutions[Apostrophe]) + node.SetCode(true) + block.Advance(1) + return node + } // Convert normal apostrophes. This is probably more flexible than necessary but // converts any apostrophe in between two alphanumerics. if len(line) > 1 && (unicode.IsDigit(before) || unicode.IsLetter(before)) && (unicode.IsLetter(util.ToRune(line, 1))) { From 5e24a624003c0692004366af74d79735cdbd6001 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 17 Feb 2022 10:13:18 -0600 Subject: [PATCH 4/5] add comment to clarify case --- extension/typographer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/extension/typographer.go b/extension/typographer.go index a788228..690de1e 100644 --- a/extension/typographer.go +++ b/extension/typographer.go @@ -268,6 +268,7 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser return node } if s.Substitutions[RightSingleQuote] != nil { + // plural possesives and abbreviations: Smiths', doin' if len(line) > 1 && unicode.IsSpace(util.ToRune(line, 0)) || unicode.IsPunct(util.ToRune(line, 0)) && (len(line) > 2 && !unicode.IsDigit(util.ToRune(line, 1))) { node := gast.NewString(s.Substitutions[RightSingleQuote]) node.SetCode(true) From 7aa0ead60c94defac9c288cba1eb10d997934a55 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 17 Feb 2022 10:13:49 -0600 Subject: [PATCH 5/5] remove log --- extension/typographer.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/extension/typographer.go b/extension/typographer.go index 690de1e..f56c06f 100644 --- a/extension/typographer.go +++ b/extension/typographer.go @@ -1,7 +1,6 @@ package extension import ( - "fmt" "unicode" "github.com/yuin/goldmark" @@ -233,7 +232,6 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser } // special cases: 'twas, 'em, 'net if len(line) > 1 && (unicode.IsPunct(before) || unicode.IsSpace(before)) && (line[1] == 't' || line[1] == 'e' || line[1] == 'n' || line[1] == 'l') { - fmt.Println(string(line)) node := gast.NewString(s.Substitutions[Apostrophe]) node.SetCode(true) block.Advance(1)