1
+ /*!
2
+ * Based on 'silvenon/remark-smartypants'
3
+ * https://github.com/silvenon/remark-smartypants/pull/80
4
+ */
5
+
1
6
const visit = require ( 'unist-util-visit' ) ;
2
7
const retext = require ( 'retext' ) ;
3
8
const smartypants = require ( 'retext-smartypants' ) ;
@@ -9,12 +14,48 @@ function check(parent) {
9
14
}
10
15
11
16
module . exports = function ( options ) {
12
- const processor = retext ( ) . use ( smartypants , options ) ;
17
+ const processor = retext ( ) . use ( smartypants , {
18
+ ...options ,
19
+ // Do not replace ellipses, dashes, backticks because they change string
20
+ // length, and we couldn't guarantee right splice of text in second visit of
21
+ // tree
22
+ ellipses : false ,
23
+ dashes : false ,
24
+ backticks : false ,
25
+ } ) ;
26
+
27
+ const processor2 = retext ( ) . use ( smartypants , {
28
+ ...options ,
29
+ // Do not replace quotes because they are already replaced in the first
30
+ // processor
31
+ quotes : false ,
32
+ } ) ;
13
33
14
34
function transformer ( tree ) {
15
- visit ( tree , 'text' , ( node , index , parent ) => {
16
- if ( check ( parent ) ) node . value = String ( processor . processSync ( node . value ) ) ;
35
+ let allText = '' ;
36
+ let startIndex = 0 ;
37
+ const textOrInlineCodeNodes = [ ] ;
38
+
39
+ visit ( tree , [ 'text' , 'inlineCode' ] , ( node , _ , parent ) => {
40
+ if ( check ( parent ) ) {
41
+ if ( node . type === 'text' ) allText += node . value ;
42
+ // for the case when inlineCode contains just one part of quote: `foo'bar`
43
+ else allText += 'A' . repeat ( node . value . length ) ;
44
+ textOrInlineCodeNodes . push ( node ) ;
45
+ }
17
46
} ) ;
47
+
48
+ // Concat all text into one string, to properly replace quotes around non-"text" nodes
49
+ allText = String ( processor . processSync ( allText ) ) ;
50
+
51
+ for ( const node of textOrInlineCodeNodes ) {
52
+ const endIndex = startIndex + node . value . length ;
53
+ if ( node . type === 'text' ) {
54
+ const processedText = allText . slice ( startIndex , endIndex ) ;
55
+ node . value = String ( processor2 . processSync ( processedText ) ) ;
56
+ }
57
+ startIndex = endIndex ;
58
+ }
18
59
}
19
60
20
61
return transformer ;
0 commit comments