Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support SAS language #5399

Open
2 tasks
Mr-ZBin opened this issue Nov 20, 2023 · 4 comments
Open
2 tasks

support SAS language #5399

Mr-ZBin opened this issue Nov 20, 2023 · 4 comments

Comments

@Mr-ZBin
Copy link

Mr-ZBin commented Nov 20, 2023

Describe the feature

Hi,
Could anyone provides SAS language highlight?

Use Case

SAS is a widely used statistical language.

Proposed Solution

No response

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

ACE version used

any version

@InspiredGuy
Copy link
Contributor

Hi @Mr-ZBin, thank you for your request. Are there any formal syntax rules defined for SAS language which could be used to make a set of syntax highlighting rules? A PR to implement those would be welcome, see an example #5356

@Mr-ZBin
Copy link
Author

Mr-ZBin commented Nov 21, 2023

Hi @InspiredGuy, I'm not good at this project, but I'll try it. And there are some contents for your reference to this request.
SAS-Syntax in Visual Studio Code
SAS in pygments

Below code is what I did in mode_creator. I don't know how to use below code for the ace editor (R -> shinyAce -> aceEditor) as a mode.
Thanks for your help.

"use strict";

var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var SASHighlightRules = function () {

    var builtins_macros = (
        "bquote|nrbquote|cmpres|qcmpres|compstor|datatyp|" +
        "display|do|else|end|eval|global|goto|if|" +
        "index|input|keydef|label|left|length|let|" +
        "local|lowcase|macro|mend|nrquote|" +
        "nrstr|put|qleft|qlowcase|qscan|" +
        "qsubstr|qsysfunc|qtrim|quote|qupcase|scan|" +
        "str|substr|superq|syscall|sysevalf|sysexec|" +
        "sysfunc|sysget|syslput|sysprod|sysrc|sysrput|" +
        "then|to|trim|unquote|until|upcase|verify|" +
        "while|window"
    );

    var builtins_block = (
        "data|proc|run|quit"
    );

    var builtins_conditionals = (
        "do|if|then|else|end|until|while"
    );

    var builtins_operators = (
        "eq|gt|ge|le|lt|ne"
    );

    var builtins_statements = (
        "abort|array|attrib|by|call|cards|cards4|" +
        "catname|continue|datalines|datalines4|delete|delim|" +
        "delimiter|display|dm|drop|endsas|error|file|" +
        "filename|footnote|format|goto|in|infile|informat|" +
        "input|keep|keestorage.modifierp|label|leave|length|libname|link|" +
        "list|lostcard|merge|missing|modify|options|output|" +
        "out|page|put|redirect|remove|rename|replace|" +
        "retain|return|select|set|skip|startsas|stop|" +
        "title|update|waitsas|where|window|x|systask"
    );

    var builtins_sql = (
        "add|and|alter|as|cascade|check|create|" +
        "delete|describe|distinct|drop|foreign|from|" +
        "group|having|index|insert|into|in|key|like|" +
        "message|modify|msgtype|not|null|on|or|" +
        "order|primary|references|reset|restrict|select|" +
        "set|table|unique|update|validate|view|where"
    );

    var builtins_functions = (
        "abs|addr|airy|arcos|arsin|atan|attrc|" +
        "attrn|band|betainv|blshift|bnot|bor|" +
        "brshift|bxor|byte|cdf|ceil|cexist|cinv|" +
        "close|cnonct|collate|compbl|compound|" +
        "compress|cos|cosh|css|curobs|cv|daccdb|" +
        "daccdbsl|daccsl|daccsyd|dacctab|dairy|date|" +
        "datejul|datepart|datetime|day|dclose|depdb|" +
        "depdbsl|depsl|depsyd|" +
        "deptab|dequote|dhms|dif|digamma|" +
        "dim|dinfo|dnum|dopen|doptname|doptnum|" +
        "dread|dropnote|dsname|erf|erfc|exist|exp|" +
        "fappend|fclose|fcol|fdelete|fetch|fetchobs|" +
        "fexist|fget|fileexist|filename|fileref|" +
        "finfo|finv|fipname|fipnamel|fipstate|floor|" +
        "fnonct|fnote|fopen|foptname|foptnum|fpoint|" +
        "fpos|fput|fread|frewind|frlen|fsep|fuzz|" +
        "fwrite|gaminv|gamma|getoption|getvarc|getvarn|" +
        "hbound|hms|hosthelp|hour|ibessel|index|" +
        "indexc|indexw|input|inputc|inputn|int|" +
        "intck|intnx|intrr|irr|jbessel|juldate|" +
        "kurtosis|lag|lbound|left|length|lgamma|" +
        "libname|libref|log|log10|log2|logpdf|logpmf|" +
        "logsdf|lowcase|max|mdy|mean|min|minute|" +
        "mod|month|mopen|mort|n|netpv|nmiss|" +
        "normal|note|npv|open|ordinal|pathname|" +
        "pdf|peek|peekc|pmf|point|poisson|poke|" +
        "probbeta|probbnml|probchi|probf|probgam|" +
        "probhypr|probit|probnegb|probnorm|probt|" +
        "put|putc|putn|qtr|quote|ranbin|rancau|" +
        "ranexp|rangam|range|rank|rannor|ranpoi|" +
        "rantbl|rantri|ranuni|repeat|resolve|reverse|" +
        "rewind|right|round|saving|scan|sdf|second|" +
        "sign|sin|sinh|skewness|soundex|spedis|" +
        "sqrt|std|stderr|stfips|stname|stnamel|" +
        "substr|sum|symget|sysget|sysmsg|sysprod|" +
        "sysrc|system|tan|tanh|time|timepart|tinv|" +
        "tnonct|today|translate|tranwrd|trigamma|" +
        "trim|trimn|trunc|uniform|upcase|uss|var|" +
        "varfmt|varinfmt|varlabel|varlen|varname|" +
        "varnum|varray|varrayx|vartype|verify|vformat|" +
        "vformatd|vformatdx|vformatn|vformatnx|vformatw|" +
        "vformatwx|vformatx|vinarray|vinarrayx|vinformat|" +
        "vinformatd|vinformatdx|vinformatn|vinformatnx|" +
        "vinformatw|vinformatwx|vinformatx|vlabel|" +
        "vlabelx|vlength|vlengthx|vname|vnamex|vtype|" +
        "vtypex|weekday|year|yyq|zipfips|zipname|" +
        "zipnamel|zipstate"
    );

    var keywordMapper = this.createKeywordMapper({
        "variable.language": builtins_macros,
        "constant.language": builtins_block,
        "keyword.control": builtins_conditionals,
        "keyword.operator": builtins_operators,
        "keyword": builtins_statements + "|" + builtins_sql,
        "support.function": builtins_functions
    }, "identifier");


    this.$rules = {
        "start": [
            {
                token: "comment.line", // multi line comment
                regex: "\\%?\\*",
                next: "line_comment"
            },
            {
                token: "comment.block", // multi line comment
                regex: "\\/\\*",
                next: "comment"
            }, 
            {
                token: "string.double",
                start: '"',
                end: '"'
            },
            {
                token: "string.single",
                start: "'",
                end: "'"
            }, 
            {
                token: "constant.numeric", // hex
                regex: "0[xX][0-9a-fA-F]+\\b"
            }, 
            {
                token: "constant.numeric", // float
                regex: "\\b[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
            }, 
            {
                token: "variable.parameter", // call macro (or function)
                regex: "\\%[a-zA-Z_]\\w*\\b"
            }, 
            {
                token: "variable", // macro variable
                regex: "\\&+[a-zA-Z_]\\w*\\.?"
            }, 
            {
                token: "storage.type", // variable length definition
                regex: "\\$\\d+\\.?"
            }, 
            {
                include: "constants"
            }
        ],
        "comment": [
            {
                token: "comment.block", // closing comment
                regex: "\\*\\/",
                next: "start"
            }, {
                defaultToken: "comment"
            }
        ],
        "line_comment": [
            {
                token: "comment.line", // closing comment
                regex: "\\;",
                next: "start"
            }, {
                defaultToken: "comment"
            }
        ],
        "constants": [{
            token: keywordMapper,
            regex: "[a-zA-Z_]\\w*\\b"
        }]
    };
    this.normalizeRules();
};

oop.inherits(SASHighlightRules, TextHighlightRules);

exports.SASHighlightRules = SASHighlightRules;

@Mr-ZBin Mr-ZBin changed the title support SAS languange support SAS language Nov 21, 2023
@Mr-ZBin
Copy link
Author

Mr-ZBin commented Nov 21, 2023

Hi @InspiredGuy, I solved my issue and you can refer it in shinyAce issue.

@InspiredGuy
Copy link
Contributor

Thank you @Mr-ZBin, a PR with your changes would be appreciated. You can follow the example in this PR #5356 to see where you need to put the new mode files, and which files you need to modify in order to make your mode available on the demo page and in TypeScript. Tests for the highlight rules are welcome as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants