diff --git a/components/prism-stan.js b/components/prism-stan.js
index 43973be9b5..cab2cfe997 100644
--- a/components/prism-stan.js
+++ b/components/prism-stan.js
@@ -1,49 +1,65 @@
-// https://mc-stan.org/docs/2_24/reference-manual/bnf-grammars.html
+(function (Prism) {
-Prism.languages.stan = {
- 'comment': /\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/,
- 'string': {
- // String literals can contain spaces and any printable ASCII characters except for " and \
- // https://mc-stan.org/docs/2_24/reference-manual/print-statements-section.html#string-literals
- pattern: /"[\x20\x21\x23-\x5B\x5D-\x7E]*"/,
- greedy: true
- },
- 'directive': {
- pattern: /^([ \t]*)#include\b.*/m,
- lookbehind: true,
- alias: 'property'
- },
+ // https://mc-stan.org/docs/2_28/reference-manual/bnf-grammars.html
- 'function-arg': {
- pattern: /(\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\s*\(\s*)[a-zA-Z]\w*/,
- lookbehind: true,
- alias: 'function'
- },
- 'constraint': {
- pattern: /(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/,
- lookbehind: true,
- inside: {
- 'expression': {
- pattern: /(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/,
- lookbehind: true,
- inside: null // see below
+ var higherOrderFunctions = /\b(?:algebra_solver|algebra_solver_newton|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect|ode_(?:adams|bdf|ckrk|rk45)(?:_tol)?|ode_adjoint_tol_ctl|reduce_sum|reduce_sum_static)\b/;
+
+ Prism.languages.stan = {
+ 'comment': /\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/,
+ 'string': {
+ // String literals can contain spaces and any printable ASCII characters except for " and \
+ // https://mc-stan.org/docs/2_24/reference-manual/print-statements-section.html#string-literals
+ pattern: /"[\x20\x21\x23-\x5B\x5D-\x7E]*"/,
+ greedy: true
+ },
+ 'directive': {
+ pattern: /^([ \t]*)#include\b.*/m,
+ lookbehind: true,
+ alias: 'property'
+ },
+
+ 'function-arg': {
+ pattern: RegExp(
+ '(' +
+ higherOrderFunctions.source +
+ /\s*\(\s*/.source +
+ ')' +
+ /[a-zA-Z]\w*/.source
+ ),
+ lookbehind: true,
+ alias: 'function'
+ },
+ 'constraint': {
+ pattern: /(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/,
+ lookbehind: true,
+ inside: {
+ 'expression': {
+ pattern: /(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/,
+ lookbehind: true,
+ inside: null // see below
+ },
+ 'property': /\b[a-z]\w*(?=\s*=)/i,
+ 'operator': /=/,
+ 'punctuation': /^<|>$|,/
+ }
+ },
+ 'keyword': [
+ {
+ pattern: /\bdata(?=\s*\{)|\b(?:functions|generated|model|parameters|quantities|transformed)\b/,
+ alias: 'program-block'
},
- 'property': /\b[a-z]\w*(?=\s*=)/i,
- 'operator': /=/,
- 'punctuation': /^<|>$|,/
- }
- },
- 'keyword': [
- /\b(?:break|cholesky_factor_corr|cholesky_factor_cov|continue|corr_matrix|cov_matrix|data|else|for|functions|generated|if|in|increment_log_prob|int|matrix|model|ordered|parameters|positive_ordered|print|quantities|real|reject|return|row_vector|simplex|target|transformed|unit_vector|vector|void|while)\b/,
- // these are functions that are known to take another function as their first argument.
- /\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\b/
- ],
- 'function': /\b[a-z]\w*(?=\s*\()/i,
- 'number': /(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:E[+-]?\d+)?\b/i,
- 'boolean': /\b(?:false|true)\b/,
+ /\b(?:array|break|cholesky_factor_corr|cholesky_factor_cov|complex|continue|corr_matrix|cov_matrix|data|else|for|if|in|increment_log_prob|int|matrix|ordered|positive_ordered|print|real|reject|return|row_vector|simplex|target|unit_vector|vector|void|while)\b/,
+ // these are functions that are known to take another function as their first argument.
+ higherOrderFunctions
+ ],
+ 'function': /\b[a-z]\w*(?=\s*\()/i,
+ 'number': /(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:E[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,
+ 'boolean': /\b(?:false|true)\b/,
+
+ 'operator': /<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/,
+ 'punctuation': /[()\[\]{},;]/
+ };
- 'operator': /<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/,
- 'punctuation': /[()\[\]{},;]/
-};
+ Prism.languages.stan.constraint.inside.expression.inside = Prism.languages.stan;
-Prism.languages.stan.constraint.inside.expression.inside = Prism.languages.stan;
+}(Prism));
diff --git a/components/prism-stan.min.js b/components/prism-stan.min.js
index 5d4f8a0f57..5db623fab4 100644
--- a/components/prism-stan.min.js
+++ b/components/prism-stan.min.js
@@ -1 +1 @@
-Prism.languages.stan={comment:/\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/,string:{pattern:/"[\x20\x21\x23-\x5B\x5D-\x7E]*"/,greedy:!0},directive:{pattern:/^([ \t]*)#include\b.*/m,lookbehind:!0,alias:"property"},"function-arg":{pattern:/(\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\s*\(\s*)[a-zA-Z]\w*/,lookbehind:!0,alias:"function"},constraint:{pattern:/(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/,lookbehind:!0,inside:{expression:{pattern:/(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/,lookbehind:!0,inside:null},property:/\b[a-z]\w*(?=\s*=)/i,operator:/=/,punctuation:/^<|>$|,/}},keyword:[/\b(?:break|cholesky_factor_corr|cholesky_factor_cov|continue|corr_matrix|cov_matrix|data|else|for|functions|generated|if|in|increment_log_prob|int|matrix|model|ordered|parameters|positive_ordered|print|quantities|real|reject|return|row_vector|simplex|target|transformed|unit_vector|vector|void|while)\b/,/\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\b/],function:/\b[a-z]\w*(?=\s*\()/i,number:/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:E[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,operator:/<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/,punctuation:/[()\[\]{},;]/},Prism.languages.stan.constraint.inside.expression.inside=Prism.languages.stan;
\ No newline at end of file
+!function(e){var r=/\b(?:algebra_solver|algebra_solver_newton|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect|ode_(?:adams|bdf|ckrk|rk45)(?:_tol)?|ode_adjoint_tol_ctl|reduce_sum|reduce_sum_static)\b/;e.languages.stan={comment:/\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/,string:{pattern:/"[\x20\x21\x23-\x5B\x5D-\x7E]*"/,greedy:!0},directive:{pattern:/^([ \t]*)#include\b.*/m,lookbehind:!0,alias:"property"},"function-arg":{pattern:RegExp("("+r.source+"\\s*\\(\\s*)[a-zA-Z]\\w*"),lookbehind:!0,alias:"function"},constraint:{pattern:/(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/,lookbehind:!0,inside:{expression:{pattern:/(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/,lookbehind:!0,inside:null},property:/\b[a-z]\w*(?=\s*=)/i,operator:/=/,punctuation:/^<|>$|,/}},keyword:[{pattern:/\bdata(?=\s*\{)|\b(?:functions|generated|model|parameters|quantities|transformed)\b/,alias:"program-block"},/\b(?:array|break|cholesky_factor_corr|cholesky_factor_cov|complex|continue|corr_matrix|cov_matrix|data|else|for|if|in|increment_log_prob|int|matrix|ordered|positive_ordered|print|real|reject|return|row_vector|simplex|target|unit_vector|vector|void|while)\b/,r],function:/\b[a-z]\w*(?=\s*\()/i,number:/(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:E[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,boolean:/\b(?:false|true)\b/,operator:/<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/,punctuation:/[()\[\]{},;]/},e.languages.stan.constraint.inside.expression.inside=e.languages.stan}(Prism);
\ No newline at end of file
diff --git a/tests/languages/stan/keyword_feature.test b/tests/languages/stan/keyword_feature.test
index fb1613ab10..139941870e 100644
--- a/tests/languages/stan/keyword_feature.test
+++ b/tests/languages/stan/keyword_feature.test
@@ -1,6 +1,8 @@
+array
break
cholesky_factor_corr
cholesky_factor_cov
+complex
continue
corr_matrix
cov_matrix
@@ -33,18 +35,32 @@ void
while
algebra_solver
+algebra_solver_newton
integrate_1d
integrate_ode
integrate_ode_bdf
integrate_ode_rk45
map_rect
+ode_adams
+ode_adams_tol
+ode_adjoint_tol_ctl
+ode_bdf
+ode_bdf_tol
+ode_ckrk
+ode_ckrk_tol
+ode_rk45
+ode_rk45_tol
+reduce_sum
+reduce_sum_static
----------------------------------------------------
[
+ ["keyword", "array"],
["keyword", "break"],
["keyword", "cholesky_factor_corr"],
["keyword", "cholesky_factor_cov"],
+ ["keyword", "complex"],
["keyword", "continue"],
["keyword", "corr_matrix"],
["keyword", "cov_matrix"],
@@ -77,11 +93,23 @@ map_rect
["keyword", "while"],
["keyword", "algebra_solver"],
+ ["keyword", "algebra_solver_newton"],
["keyword", "integrate_1d"],
["keyword", "integrate_ode"],
["keyword", "integrate_ode_bdf"],
["keyword", "integrate_ode_rk45"],
- ["keyword", "map_rect"]
+ ["keyword", "map_rect"],
+ ["keyword", "ode_adams"],
+ ["keyword", "ode_adams_tol"],
+ ["keyword", "ode_adjoint_tol_ctl"],
+ ["keyword", "ode_bdf"],
+ ["keyword", "ode_bdf_tol"],
+ ["keyword", "ode_ckrk"],
+ ["keyword", "ode_ckrk_tol"],
+ ["keyword", "ode_rk45"],
+ ["keyword", "ode_rk45_tol"],
+ ["keyword", "reduce_sum"],
+ ["keyword", "reduce_sum_static"]
]
----------------------------------------------------
diff --git a/tests/languages/stan/number_feature.test b/tests/languages/stan/number_feature.test
index 0d70a28a41..4741a872a1 100644
--- a/tests/languages/stan/number_feature.test
+++ b/tests/languages/stan/number_feature.test
@@ -1,6 +1,7 @@
0
1
24567898765
+24_56_78_98_765
0.0
1.0
@@ -8,6 +9,11 @@
2.7e3
2E-5
1.23e+3
+3.14i
+40e-3i
+1e10i
+0i
+1_2.3_4e5_6i
----------------------------------------------------
@@ -15,13 +21,19 @@
["number", "0"],
["number", "1"],
["number", "24567898765"],
+ ["number", "24_56_78_98_765"],
["number", "0.0"],
["number", "1.0"],
["number", "3.14"],
["number", "2.7e3"],
["number", "2E-5"],
- ["number", "1.23e+3"]
+ ["number", "1.23e+3"],
+ ["number", "3.14i"],
+ ["number", "40e-3i"],
+ ["number", "1e10i"],
+ ["number", "0i"],
+ ["number", "1_2.3_4e5_6i"]
]
----------------------------------------------------
diff --git a/tests/languages/stan/program-block_feature.html.test b/tests/languages/stan/program-block_feature.html.test
new file mode 100644
index 0000000000..1de0f530af
--- /dev/null
+++ b/tests/languages/stan/program-block_feature.html.test
@@ -0,0 +1,76 @@
+functions {
+ // ... function declarations and definitions ...
+}
+data {
+ // ... declarations ...
+}
+transformed data {
+ // ... declarations ... statements ...
+}
+parameters {
+ // ... declarations ...
+}
+transformed parameters {
+ // ... declarations ... statements ...
+}
+model {
+ // ... declarations ... statements ...
+}
+generated quantities {
+ // ... declarations ... statements ...
+}
+
+// data-only quantifiers
+real foo(data real x) {
+ return x^2;
+}
+
+----------------------------------------------------
+
+functions
+{
+
+}
+data
+{
+
+}
+transformed
+data
+{
+
+}
+parameters
+{
+
+}
+transformed
+parameters
+{
+
+}
+model
+{
+
+}
+generated
+quantities
+{
+
+}
+
+
+real
+foo
+(
+data
+real
+x
+)
+{
+return
+x
+^
+2
+;
+}