@@ -41,23 +41,95 @@ if(window.jekyllEnv !== 'spec-pdf') {
41
41
) ;
42
42
}
43
43
44
- // no language auto-detect so that EBNF isn't detected as scala
45
- hljs . configure ( {
46
- languages : [ ]
44
+ // See https://github.com/highlightjs/highlight.js/issues/2889 for additional context.
45
+ function renderMath ( { el, result, text} ) {
46
+
47
+ const re = RegExp ( '´' , 'g' ) ;
48
+
49
+ const spans = [ ] ;
50
+
51
+ // get the spans of all math elements
52
+ while ( match = re . exec ( text ) ) {
53
+ const start = match . index ;
54
+ match = re . exec ( text ) ;
55
+ if ( match == null ) {
56
+ break ;
57
+ } else {
58
+ const end = match . index + 1 ;
59
+ spans . push ( { start, end} ) ;
60
+ }
61
+ }
62
+
63
+ // render spans using katex
64
+ for ( const span of spans ) {
65
+ const { start, end} = span ;
66
+ const str = text . substring ( start + 1 , end - 1 ) ;
67
+ const parent = new DocumentFragment ( ) ;
68
+ katex . render ( str , parent , { throwOnError : false } ) ;
69
+ const children = parent . children ;
70
+ // TODO: Double check mutiple elements aren't possible
71
+ if ( children . length == 1 ) {
72
+ span . span = children [ 0 ] ;
73
+ }
74
+ }
75
+
76
+ // Here we start the merging between the katex output and highlight output.
77
+ if ( spans . length != 0 ) {
78
+
79
+ // This is essentially our iterator
80
+ var offset = 0 ;
81
+ var span = spans . shift ( ) ;
82
+ var child = el . firstChild ;
83
+
84
+ // highlight only supports one level of nesting.
85
+ while ( child ) {
86
+ if ( child instanceof Text ) {
87
+ const str = child . wholeText ;
88
+ const start = offset ;
89
+ const end = start + str . length ;
90
+
91
+ if ( span . start >= start && span . end <= end ) {
92
+ const beforeText = str . substring ( 0 , span . start - start ) ;
93
+ if ( beforeText ) {
94
+ el . insertBefore ( new Text ( beforeText ) , child ) ;
95
+ }
96
+
97
+ const afterText = str . substring ( span . end - start ) ;
98
+ child = el . replaceChild ( span . span , child ) ;
99
+
100
+ if ( afterText ) {
101
+ el . insertAfter ( child , new Text ( afterText ) , child ) ;
102
+ }
103
+
104
+ offset = span . end ;
105
+
106
+ } else {
107
+ offset = end ;
108
+ }
109
+ } else if ( child . tagName ) {
110
+ offset += str . length ;
111
+ }
112
+
113
+ child = child . nextSibling ;
114
+ }
115
+ }
116
+ }
117
+
118
+ hljs . addPlugin ( {
119
+ 'after:highlightElement' : renderMath
47
120
} ) ;
48
121
49
122
// KaTeX configuration
50
123
document . addEventListener ( "DOMContentLoaded" , function ( ) {
51
124
renderMathInElement ( document . body , {
52
- delimiters : [
53
- { left : "´" , right : "´" , display : false } , // "display: false" -> inline
54
- { left : "$$" , right : "$$" , display : true }
55
- ] ,
56
- ignoredTags : [ 'script' , 'noscript' , 'style' , 'textarea' ] ,
125
+ delimiters : [
126
+ { left : "´" , right : "´" , display : false } , // "display: false" -> inline
127
+ { left : "$$" , right : "$$" , display : true }
128
+ ] ,
129
+ // We ignore 'code' here, because highlight will deal with it.
130
+ ignoredTags : [ 'script' , 'noscript' , 'style' , 'code' ] ,
57
131
} ) ;
58
- // syntax highlighting after KaTeX is loaded,
59
- // so that math can be used in code blocks
60
- hljs . initHighlighting ( ) ;
132
+ hljs . highlightAll ( ) ;
61
133
$ ( "pre nobr" ) . addClass ( "fixws" ) ;
62
134
// point when all necessary js is done, so PDF to be rendered
63
135
window . status = "loaded" ;
0 commit comments