@@ -23,7 +23,8 @@ function isSafeBoundary(character_code, delimiter_code, md) {
23
23
return false ;
24
24
}
25
25
26
- function math_input ( state , silent , delimiter_code ) {
26
+ let inlineMath = delimiter => ( state , silent ) => {
27
+ let delimiter_code = delimiter . charCodeAt ( 0 ) ;
27
28
let pos = state . pos ,
28
29
posMax = state . posMax ;
29
30
@@ -71,35 +72,20 @@ function math_input(state, silent, delimiter_code) {
71
72
let token = state . push ( "html_raw" , "" , 0 ) ;
72
73
73
74
const escaped = state . md . utils . escapeHtml ( data ) ;
74
- let math_class = delimiter_code === 36 ? "'math '" : "'asciimath '" ;
75
+ let math_class = delimiter_code === 37 /* % */ ? "'asciimath '" : "'math '" ;
75
76
token . content = `<span class=${ math_class } >${ escaped } </span>` ;
76
77
state . pos = found + 1 ;
77
78
return true ;
78
79
}
79
80
80
- function inlineMath ( state , silent ) {
81
- return math_input ( state , silent , 36 /* $ */ ) ;
82
- }
83
-
84
- function asciiMath ( state , silent ) {
85
- return math_input ( state , silent , 37 /* % */ ) ;
86
- }
87
-
88
- function isBlockMarker ( state , start , max , md ) {
89
- if ( state . src . charCodeAt ( start ) !== 36 /* $ */ ) {
90
- return false ;
91
- }
81
+ function isBlockMarker ( state , start , max , md , blockMarker ) {
92
82
93
- start ++ ;
94
-
95
- if ( state . src . charCodeAt ( start ) !== 36 /* $ */ ) {
83
+ if ( ! state . src . startsWith ( blockMarker , start ) ) {
96
84
return false ;
97
85
}
98
86
99
- start ++ ;
100
-
101
- // ensure we only have newlines after our $$
102
- for ( let i = start ; i < max ; i ++ ) {
87
+ // ensure we only have spaces and newline after blockmarker
88
+ for ( let i = start + blockMarker . length ; i < max ; i ++ ) {
103
89
if ( ! md . utils . isSpace ( state . src . charCodeAt ( i ) ) ) {
104
90
return false ;
105
91
}
@@ -108,11 +94,11 @@ function isBlockMarker(state, start, max, md) {
108
94
return true ;
109
95
}
110
96
111
- function blockMath ( state , startLine , endLine , silent ) {
97
+ let blockMath = blockMarker => ( state , startLine , endLine , silent ) => {
112
98
let start = state . bMarks [ startLine ] + state . tShift [ startLine ] ,
113
99
max = state . eMarks [ startLine ] ;
114
100
115
- if ( ! isBlockMarker ( state , start , max , state . md ) ) {
101
+ if ( ! isBlockMarker ( state , start , max , state . md , blockMarker ) ) {
116
102
return false ;
117
103
}
118
104
@@ -125,7 +111,7 @@ function blockMath(state, startLine, endLine, silent) {
125
111
for ( ; ; ) {
126
112
nextLine ++ ;
127
113
128
- // unclosed $$ is considered math
114
+ // Unclosed blockmarker is considered math
129
115
if ( nextLine >= endLine ) {
130
116
break ;
131
117
}
@@ -135,7 +121,8 @@ function blockMath(state, startLine, endLine, silent) {
135
121
state ,
136
122
state . bMarks [ nextLine ] + state . tShift [ nextLine ] ,
137
123
state . eMarks [ nextLine ] ,
138
- state . md
124
+ state . md ,
125
+ blockMarker . replace ( '\\begin{' , '\\end{' )
139
126
)
140
127
) {
141
128
closed = true ;
@@ -145,11 +132,15 @@ function blockMath(state, startLine, endLine, silent) {
145
132
146
133
let token = state . push ( "html_raw" , "" , 0 ) ;
147
134
148
- let endContent = closed ? state . eMarks [ nextLine - 1 ] : state . eMarks [ nextLine ] ;
149
- let content = state . src . slice (
150
- state . bMarks [ startLine + 1 ] + state . tShift [ startLine + 1 ] ,
151
- endContent
152
- ) ;
135
+ // Blockmarker starting with \begin{ end ending with '\end{'
136
+ // needs to be passed to the TeX engine
137
+ let endContent = blockMarker . startsWith ( '\\begin{' ) || ! closed ?
138
+ state . eMarks [ nextLine ] : state . eMarks [ nextLine - 1 ] ;
139
+
140
+ let startContent = blockMarker . startsWith ( '\\begin{' ) ?
141
+ state . bMarks [ startLine ] : state . bMarks [ startLine + 1 ] + state . tShift [ startLine + 1 ] ;
142
+
143
+ let content = state . src . slice ( startContent , endContent ) ;
153
144
154
145
const escaped = state . md . utils . escapeHtml ( content ) ;
155
146
token . content = `<div class='math'>\n${ escaped } \n</div>\n` ;
@@ -165,18 +156,34 @@ export function setup(helper) {
165
156
}
166
157
167
158
let enable_asciimath ;
159
+ let inlineDelimiters , blockDelimiters ;
168
160
helper . registerOptions ( ( opts , siteSettings ) => {
169
161
opts . features . math = siteSettings . discourse_math_enabled ;
170
162
enable_asciimath = siteSettings . discourse_math_enable_asciimath ;
163
+ inlineDelimiters = siteSettings . discourse_math_inline_delimiters ;
164
+ blockDelimiters = siteSettings . discourse_math_block_delimiters ;
171
165
} ) ;
172
166
173
167
helper . registerPlugin ( md => {
174
168
if ( enable_asciimath ) {
175
- md . inline . ruler . after ( "escape" , "asciimath" , asciiMath ) ;
169
+ md . inline . ruler . after ( "escape" , "asciimath" , inlineMath ( '%' ) ) ;
170
+ }
171
+ if ( inlineDelimiters ) {
172
+ inlineDelimiters . split ( '|' ) . forEach ( delim => {
173
+ // We expect only one character
174
+ // for inline math delimiter
175
+ let d = delim . trim ( ) ;
176
+ if ( d . length !== 1 ) return ;
177
+ md . inline . ruler . after ( "escape" , "math" , inlineMath ( d ) ) ;
178
+ } ) ;
179
+ }
180
+ if ( blockDelimiters ) {
181
+ blockDelimiters . split ( '|' ) . forEach ( delim => {
182
+ let d = delim . trim ( ) ;
183
+ md . block . ruler . after ( "code" , "math" , blockMath ( delim ) , {
184
+ alt : [ "paragraph" , "reference" , "blockquote" , "list" ]
185
+ } ) ;
186
+ } ) ;
176
187
}
177
- md . inline . ruler . after ( "escape" , "math" , inlineMath ) ;
178
- md . block . ruler . after ( "code" , "math" , blockMath , {
179
- alt : [ "paragraph" , "reference" , "blockquote" , "list" ]
180
- } ) ;
181
188
} ) ;
182
189
}
0 commit comments