@@ -39,7 +39,7 @@ func isdigit(c byte) bool {
39
39
return c >= '0' && c <= '9'
40
40
}
41
41
42
- func smartQuoteHelper (out * bytes.Buffer , previousChar byte , nextChar byte , quote byte , isOpen * bool ) bool {
42
+ func smartQuoteHelper (out * bytes.Buffer , previousChar byte , nextChar byte , quote byte , isOpen * bool , addNBSP bool ) bool {
43
43
// edge of the buffer is likely to be a tag that we don't get to see,
44
44
// so we treat it like text sometimes
45
45
@@ -96,6 +96,12 @@ func smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote
96
96
* isOpen = false
97
97
}
98
98
99
+ // Note that with the limited lookahead, this non-breaking
100
+ // space will also be appended to single double quotes.
101
+ if addNBSP && ! * isOpen {
102
+ out .WriteString (" " )
103
+ }
104
+
99
105
out .WriteByte ('&' )
100
106
if * isOpen {
101
107
out .WriteByte ('l' )
@@ -104,6 +110,11 @@ func smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote
104
110
}
105
111
out .WriteByte (quote )
106
112
out .WriteString ("quo;" )
113
+
114
+ if addNBSP && * isOpen {
115
+ out .WriteString (" " )
116
+ }
117
+
107
118
return true
108
119
}
109
120
@@ -116,7 +127,7 @@ func smartSingleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byt
116
127
if len (text ) >= 3 {
117
128
nextChar = text [2 ]
118
129
}
119
- if smartQuoteHelper (out , previousChar , nextChar , 'd' , & smrt .inDoubleQuote ) {
130
+ if smartQuoteHelper (out , previousChar , nextChar , 'd' , & smrt .inDoubleQuote , false ) {
120
131
return 1
121
132
}
122
133
}
@@ -141,7 +152,7 @@ func smartSingleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byt
141
152
if len (text ) > 1 {
142
153
nextChar = text [1 ]
143
154
}
144
- if smartQuoteHelper (out , previousChar , nextChar , 's' , & smrt .inSingleQuote ) {
155
+ if smartQuoteHelper (out , previousChar , nextChar , 's' , & smrt .inSingleQuote , false ) {
145
156
return 0
146
157
}
147
158
@@ -205,13 +216,13 @@ func smartDashLatex(out *bytes.Buffer, smrt *smartypantsData, previousChar byte,
205
216
return 0
206
217
}
207
218
208
- func smartAmpVariant (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte , quote byte ) int {
219
+ func smartAmpVariant (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte , quote byte , addNBSP bool ) int {
209
220
if bytes .HasPrefix (text , []byte (""" )) {
210
221
nextChar := byte (0 )
211
222
if len (text ) >= 7 {
212
223
nextChar = text [6 ]
213
224
}
214
- if smartQuoteHelper (out , previousChar , nextChar , quote , & smrt .inDoubleQuote ) {
225
+ if smartQuoteHelper (out , previousChar , nextChar , quote , & smrt .inDoubleQuote , addNBSP ) {
215
226
return 5
216
227
}
217
228
}
@@ -224,12 +235,15 @@ func smartAmpVariant(out *bytes.Buffer, smrt *smartypantsData, previousChar byte
224
235
return 0
225
236
}
226
237
227
- func smartAmp (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte ) int {
228
- return smartAmpVariant (out , smrt , previousChar , text , 'd' )
229
- }
238
+ func smartAmp (angledQuotes , addNBSP bool ) func (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte ) int {
239
+ var quote byte = 'd'
240
+ if angledQuotes {
241
+ quote = 'a'
242
+ }
230
243
231
- func smartAmpAngledQuote (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte ) int {
232
- return smartAmpVariant (out , smrt , previousChar , text , 'a' )
244
+ return func (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte ) int {
245
+ return smartAmpVariant (out , smrt , previousChar , text , quote , addNBSP )
246
+ }
233
247
}
234
248
235
249
func smartPeriod (out * bytes.Buffer , smrt * smartypantsData , previousChar byte , text []byte ) int {
@@ -253,7 +267,7 @@ func smartBacktick(out *bytes.Buffer, smrt *smartypantsData, previousChar byte,
253
267
if len (text ) >= 3 {
254
268
nextChar = text [2 ]
255
269
}
256
- if smartQuoteHelper (out , previousChar , nextChar , 'd' , & smrt .inDoubleQuote ) {
270
+ if smartQuoteHelper (out , previousChar , nextChar , 'd' , & smrt .inDoubleQuote , false ) {
257
271
return 1
258
272
}
259
273
}
@@ -337,7 +351,7 @@ func smartDoubleQuoteVariant(out *bytes.Buffer, smrt *smartypantsData, previousC
337
351
if len (text ) > 1 {
338
352
nextChar = text [1 ]
339
353
}
340
- if ! smartQuoteHelper (out , previousChar , nextChar , quote , & smrt .inDoubleQuote ) {
354
+ if ! smartQuoteHelper (out , previousChar , nextChar , quote , & smrt .inDoubleQuote , false ) {
341
355
out .WriteString (""" )
342
356
}
343
357
@@ -367,14 +381,30 @@ type smartCallback func(out *bytes.Buffer, smrt *smartypantsData, previousChar b
367
381
368
382
type smartypantsRenderer [256 ]smartCallback
369
383
384
+ var (
385
+ smartAmpAngled = smartAmp (true , false )
386
+ smartAmpAngledNBSP = smartAmp (true , true )
387
+ smartAmpRegular = smartAmp (false , false )
388
+ smartAmpRegularNBSP = smartAmp (false , true )
389
+ )
390
+
370
391
func smartypants (flags int ) * smartypantsRenderer {
371
392
r := new (smartypantsRenderer )
393
+ addNBSP := flags & HTML_SMARTYPANTS_QUOTES_NBSP != 0
372
394
if flags & HTML_SMARTYPANTS_ANGLED_QUOTES == 0 {
373
395
r ['"' ] = smartDoubleQuote
374
- r ['&' ] = smartAmp
396
+ if ! addNBSP {
397
+ r ['&' ] = smartAmpRegular
398
+ } else {
399
+ r ['&' ] = smartAmpRegularNBSP
400
+ }
375
401
} else {
376
402
r ['"' ] = smartAngledDoubleQuote
377
- r ['&' ] = smartAmpAngledQuote
403
+ if ! addNBSP {
404
+ r ['&' ] = smartAmpAngled
405
+ } else {
406
+ r ['&' ] = smartAmpAngledNBSP
407
+ }
378
408
}
379
409
r ['\'' ] = smartSingleQuote
380
410
r ['(' ] = smartParens
0 commit comments