UNPKG

9.99 kBJavaScriptView Raw
1/*
2Language: Stan
3Description: The Stan probabilistic programming language
4Author: Sean Pinkney <sean.pinkney@gmail.com>
5Website: http://mc-stan.org/
6Category: scientific
7*/
8
9function stan(hljs) {
10 const regex = hljs.regex;
11 // variable names cannot conflict with block identifiers
12 const BLOCKS = [
13 'functions',
14 'model',
15 'data',
16 'parameters',
17 'quantities',
18 'transformed',
19 'generated'
20 ];
21
22 const STATEMENTS = [
23 'for',
24 'in',
25 'if',
26 'else',
27 'while',
28 'break',
29 'continue',
30 'return'
31 ];
32
33 const TYPES = [
34 'array',
35 'complex',
36 'int',
37 'real',
38 'vector',
39 'ordered',
40 'positive_ordered',
41 'simplex',
42 'unit_vector',
43 'row_vector',
44 'matrix',
45 'cholesky_factor_corr|10',
46 'cholesky_factor_cov|10',
47 'corr_matrix|10',
48 'cov_matrix|10',
49 'void'
50 ];
51
52 // to get the functions list
53 // clone the [stan-docs repo](https://github.com/stan-dev/docs)
54 // then cd into it and run this bash script https://gist.github.com/joshgoebel/dcd33f82d4059a907c986049893843cf
55 //
56 // the output files are
57 // distributions_quoted.txt
58 // functions_quoted.txt
59
60 const FUNCTIONS = [
61 'Phi',
62 'Phi_approx',
63 'abs',
64 'acos',
65 'acosh',
66 'add_diag',
67 'algebra_solver',
68 'algebra_solver_newton',
69 'append_array',
70 'append_col',
71 'append_row',
72 'asin',
73 'asinh',
74 'atan',
75 'atan2',
76 'atanh',
77 'bessel_first_kind',
78 'bessel_second_kind',
79 'binary_log_loss',
80 'binomial_coefficient_log',
81 'block',
82 'cbrt',
83 'ceil',
84 'chol2inv',
85 'cholesky_decompose',
86 'choose',
87 'col',
88 'cols',
89 'columns_dot_product',
90 'columns_dot_self',
91 'conj',
92 'cos',
93 'cosh',
94 'cov_exp_quad',
95 'crossprod',
96 'csr_extract_u',
97 'csr_extract_v',
98 'csr_extract_w',
99 'csr_matrix_times_vector',
100 'csr_to_dense_matrix',
101 'cumulative_sum',
102 'determinant',
103 'diag_matrix',
104 'diag_post_multiply',
105 'diag_pre_multiply',
106 'diagonal',
107 'digamma',
108 'dims',
109 'distance',
110 'dot_product',
111 'dot_self',
112 'eigenvalues_sym',
113 'eigenvectors_sym',
114 'erf',
115 'erfc',
116 'exp',
117 'exp2',
118 'expm1',
119 'fabs',
120 'falling_factorial',
121 'fdim',
122 'floor',
123 'fma',
124 'fmax',
125 'fmin',
126 'fmod',
127 'gamma_p',
128 'gamma_q',
129 'generalized_inverse',
130 'get_imag',
131 'get_lp',
132 'get_real',
133 'head',
134 'hmm_hidden_state_prob',
135 'hmm_marginal',
136 'hypot',
137 'identity_matrix',
138 'inc_beta',
139 'int_step',
140 'integrate_1d',
141 'integrate_ode',
142 'integrate_ode_adams',
143 'integrate_ode_bdf',
144 'integrate_ode_rk45',
145 'inv',
146 'inv_Phi',
147 'inv_cloglog',
148 'inv_logit',
149 'inv_sqrt',
150 'inv_square',
151 'inverse',
152 'inverse_spd',
153 'is_inf',
154 'is_nan',
155 'lambert_w0',
156 'lambert_wm1',
157 'lbeta',
158 'lchoose',
159 'ldexp',
160 'lgamma',
161 'linspaced_array',
162 'linspaced_int_array',
163 'linspaced_row_vector',
164 'linspaced_vector',
165 'lmgamma',
166 'lmultiply',
167 'log',
168 'log1m',
169 'log1m_exp',
170 'log1m_inv_logit',
171 'log1p',
172 'log1p_exp',
173 'log_determinant',
174 'log_diff_exp',
175 'log_falling_factorial',
176 'log_inv_logit',
177 'log_inv_logit_diff',
178 'log_mix',
179 'log_modified_bessel_first_kind',
180 'log_rising_factorial',
181 'log_softmax',
182 'log_sum_exp',
183 'logit',
184 'machine_precision',
185 'map_rect',
186 'matrix_exp',
187 'matrix_exp_multiply',
188 'matrix_power',
189 'max',
190 'mdivide_left_spd',
191 'mdivide_left_tri_low',
192 'mdivide_right_spd',
193 'mdivide_right_tri_low',
194 'mean',
195 'min',
196 'modified_bessel_first_kind',
197 'modified_bessel_second_kind',
198 'multiply_log',
199 'multiply_lower_tri_self_transpose',
200 'negative_infinity',
201 'norm',
202 'not_a_number',
203 'num_elements',
204 'ode_adams',
205 'ode_adams_tol',
206 'ode_adjoint_tol_ctl',
207 'ode_bdf',
208 'ode_bdf_tol',
209 'ode_ckrk',
210 'ode_ckrk_tol',
211 'ode_rk45',
212 'ode_rk45_tol',
213 'one_hot_array',
214 'one_hot_int_array',
215 'one_hot_row_vector',
216 'one_hot_vector',
217 'ones_array',
218 'ones_int_array',
219 'ones_row_vector',
220 'ones_vector',
221 'owens_t',
222 'polar',
223 'positive_infinity',
224 'pow',
225 'print',
226 'prod',
227 'proj',
228 'qr_Q',
229 'qr_R',
230 'qr_thin_Q',
231 'qr_thin_R',
232 'quad_form',
233 'quad_form_diag',
234 'quad_form_sym',
235 'quantile',
236 'rank',
237 'reduce_sum',
238 'reject',
239 'rep_array',
240 'rep_matrix',
241 'rep_row_vector',
242 'rep_vector',
243 'reverse',
244 'rising_factorial',
245 'round',
246 'row',
247 'rows',
248 'rows_dot_product',
249 'rows_dot_self',
250 'scale_matrix_exp_multiply',
251 'sd',
252 'segment',
253 'sin',
254 'singular_values',
255 'sinh',
256 'size',
257 'softmax',
258 'sort_asc',
259 'sort_desc',
260 'sort_indices_asc',
261 'sort_indices_desc',
262 'sqrt',
263 'square',
264 'squared_distance',
265 'step',
266 'sub_col',
267 'sub_row',
268 'sum',
269 'svd_U',
270 'svd_V',
271 'symmetrize_from_lower_tri',
272 'tail',
273 'tan',
274 'tanh',
275 'target',
276 'tcrossprod',
277 'tgamma',
278 'to_array_1d',
279 'to_array_2d',
280 'to_complex',
281 'to_matrix',
282 'to_row_vector',
283 'to_vector',
284 'trace',
285 'trace_gen_quad_form',
286 'trace_quad_form',
287 'trigamma',
288 'trunc',
289 'uniform_simplex',
290 'variance',
291 'zeros_array',
292 'zeros_int_array',
293 'zeros_row_vector'
294 ];
295
296 const DISTRIBUTIONS = [
297 'bernoulli',
298 'bernoulli_logit',
299 'bernoulli_logit_glm',
300 'beta',
301 'beta_binomial',
302 'beta_proportion',
303 'binomial',
304 'binomial_logit',
305 'categorical',
306 'categorical_logit',
307 'categorical_logit_glm',
308 'cauchy',
309 'chi_square',
310 'dirichlet',
311 'discrete_range',
312 'double_exponential',
313 'exp_mod_normal',
314 'exponential',
315 'frechet',
316 'gamma',
317 'gaussian_dlm_obs',
318 'gumbel',
319 'hmm_latent',
320 'hypergeometric',
321 'inv_chi_square',
322 'inv_gamma',
323 'inv_wishart',
324 'lkj_corr',
325 'lkj_corr_cholesky',
326 'logistic',
327 'lognormal',
328 'multi_gp',
329 'multi_gp_cholesky',
330 'multi_normal',
331 'multi_normal_cholesky',
332 'multi_normal_prec',
333 'multi_student_t',
334 'multinomial',
335 'multinomial_logit',
336 'neg_binomial',
337 'neg_binomial_2',
338 'neg_binomial_2_log',
339 'neg_binomial_2_log_glm',
340 'normal',
341 'normal_id_glm',
342 'ordered_logistic',
343 'ordered_logistic_glm',
344 'ordered_probit',
345 'pareto',
346 'pareto_type_2',
347 'poisson',
348 'poisson_log',
349 'poisson_log_glm',
350 'rayleigh',
351 'scaled_inv_chi_square',
352 'skew_double_exponential',
353 'skew_normal',
354 'std_normal',
355 'student_t',
356 'uniform',
357 'von_mises',
358 'weibull',
359 'wiener',
360 'wishart'
361 ];
362
363 const BLOCK_COMMENT = hljs.COMMENT(
364 /\/\*/,
365 /\*\//,
366 {
367 relevance: 0,
368 contains: [
369 {
370 scope: 'doctag',
371 match: /@(return|param)/
372 }
373 ]
374 }
375 );
376
377 const INCLUDE = {
378 scope: 'meta',
379 begin: /#include\b/,
380 end: /$/,
381 contains: [
382 {
383 match: /[a-z][a-z-._]+/,
384 scope: 'string'
385 },
386 hljs.C_LINE_COMMENT_MODE
387 ]
388 };
389
390 const RANGE_CONSTRAINTS = [
391 "lower",
392 "upper",
393 "offset",
394 "multiplier"
395 ];
396
397 return {
398 name: 'Stan',
399 aliases: [ 'stanfuncs' ],
400 keywords: {
401 $pattern: hljs.IDENT_RE,
402 title: BLOCKS,
403 type: TYPES,
404 keyword: STATEMENTS,
405 built_in: FUNCTIONS
406 },
407 contains: [
408 hljs.C_LINE_COMMENT_MODE,
409 INCLUDE,
410 hljs.HASH_COMMENT_MODE,
411 BLOCK_COMMENT,
412 {
413 scope: 'built_in',
414 match: /\s(pi|e|sqrt2|log2|log10)(?=\()/,
415 relevance: 0
416 },
417 {
418 match: regex.concat(/[<,]\s*/, regex.either(...RANGE_CONSTRAINTS), /\s*=/),
419 keywords: RANGE_CONSTRAINTS
420 },
421 {
422 scope: 'keyword',
423 match: /\btarget(?=\s*\+=)/,
424 },
425 {
426 // highlights the 'T' in T[,] for only Stan language distributrions
427 match: [
428 /~\s*/,
429 regex.either(...DISTRIBUTIONS),
430 /(?:\(\))/,
431 /\s*T(?=\s*\[)/
432 ],
433 scope: {
434 2: "built_in",
435 4: "keyword"
436 }
437 },
438 {
439 // highlights distributions that end with special endings
440 scope: 'built_in',
441 keywords: DISTRIBUTIONS,
442 begin: regex.concat(/\w*/, regex.either(...DISTRIBUTIONS), /(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/)
443 },
444 {
445 // highlights distributions after ~
446 begin: [
447 /~/,
448 /\s*/,
449 regex.concat(regex.either(...DISTRIBUTIONS), /(?=\s*[\(.*\)])/)
450 ],
451 scope: { 3: "built_in" }
452 },
453 {
454 // highlights user defined distributions after ~
455 begin: [
456 /~/,
457 /\s*\w+(?=\s*[\(.*\)])/,
458 '(?!.*/\b(' + regex.either(...DISTRIBUTIONS) + ')\b)'
459 ],
460 scope: { 2: "title.function" }
461 },
462 {
463 // highlights user defined distributions with special endings
464 scope: 'title.function',
465 begin: /\w*(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/
466 },
467 {
468 scope: 'number',
469 match: regex.concat(
470 // Comes from @RunDevelopment accessed 11/29/2021 at
471 // https://github.com/PrismJS/prism/blob/c53ad2e65b7193ab4f03a1797506a54bbb33d5a2/components/prism-stan.js#L56
472
473 // start of big noncapture group which
474 // 1. gets numbers that are by themselves
475 // 2. numbers that are separated by _
476 // 3. numbers that are separted by .
477 /(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)/,
478 // grabs scientific notation
479 // grabs complex numbers with i
480 /(?:[eE][+-]?\d+(?:_\d+)*)?i?(?!\w)/
481 ),
482 relevance: 0
483 },
484 {
485 scope: 'string',
486 begin: /"/,
487 end: /"/
488 }
489 ]
490 };
491}
492
493module.exports = stan;