Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
416922d
initial commit of proc_r embedded lang test
Wizzzzzzard Dec 4, 2025
74a5d31
adding R language options to client and notebook
Wizzzzzzard Dec 5, 2025
0231587
adding some R Code test fixtures
Wizzzzzzard Dec 5, 2025
8f22394
fixing rlang testfixture file name
Wizzzzzzard Dec 5, 2025
97489e5
adding a print statement to debug rlang zonelist
Wizzzzzzard Dec 5, 2025
696bddd
updating debug function for zone_type assertions
Wizzzzzzard Dec 5, 2025
a05b28f
DCO Remediation Commit for Elijah Cúchulainn Reid <56865341+Wizzzzzza…
Wizzzzzzard Dec 5, 2025
29dfd9a
Updating Lexer to correctly parse PROC RLANG code
Wizzzzzzard Dec 5, 2025
0e2b746
Adding PROC_RLANG to CodeZoneManager
Wizzzzzzard Dec 5, 2025
398c156
Adding R as an option to the parser for formatting
Wizzzzzzard Dec 5, 2025
ca52898
DCO Remediation Commit for Elijah Cúchulainn Reid <56865341+Wizzzzzza…
Wizzzzzzard Dec 5, 2025
454a6ab
test with simpler rlang script
Wizzzzzzard Dec 5, 2025
5e4da15
resetting to more complex Rlang file
Wizzzzzzard Dec 5, 2025
a3be20b
fixing file
Wizzzzzzard Dec 5, 2025
412995f
adding more rlang tests to match pre-existing lua and python ones
Wizzzzzzard Dec 5, 2025
e62c8e8
reverting embedded lang test assert for rlang
Wizzzzzzard Dec 5, 2025
c5f8f7f
updating references to "rlang" as a language to "r" to work better wi…
Wizzzzzzard Dec 5, 2025
d4da7ad
making spacing a bit nicer
Wizzzzzzard Dec 5, 2025
7e58b1c
tweaking R UID to see if it makes a difference
Wizzzzzzard Dec 5, 2025
925ff77
Updating notebook with correctly highlighted R code
Wizzzzzzard Dec 5, 2025
9e1b66a
uploading notebook with R output
Wizzzzzzard Dec 5, 2025
3b41802
making the rlang id match python
Wizzzzzzard Dec 5, 2025
54f72e3
Updating references to languages in docs to include R
Wizzzzzzard Dec 5, 2025
82d5f26
Including R changes in the Changelog
Wizzzzzzard Dec 5, 2025
ca092d2
removing rlang case now that references have been updated to r
Wizzzzzzard Dec 5, 2025
adc239c
removing debug function from CodeZoneManager
Wizzzzzzard Dec 5, 2025
18cba79
Simplifying R comment/string regex in Lexer
Wizzzzzzard Dec 5, 2025
4036233
updating Code Document to only require r
Wizzzzzzard Dec 5, 2025
ec3df3b
Adding tests for theoretical Proc Julia
Wizzzzzzard Dec 8, 2025
602891f
Adding Julia syntax highlighting package
Wizzzzzzard Dec 8, 2025
5a77c31
Adding Julia support for parsing and code zones
Wizzzzzzard Dec 8, 2025
65c9393
adding func to detect and wrap Julia Code in Notebook
Wizzzzzzard Dec 8, 2025
b81d24e
adding code to export Julia code to HTML and/or SAS formats
Wizzzzzzard Dec 8, 2025
cf4dbe9
fixing test fixture by adding missing newline
Wizzzzzzard Dec 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add the ability to sort columns in data viewer and view column properties ([#1622](https://github.com/sassoftware/vscode-sas-extension/pull/1622))
- Add code comment collapsing ([#1638](https://github.com/sassoftware/vscode-sas-extension/pull/1638))
- Add ability to view dataset properties ([#1631](https://github.com/sassoftware/vscode-sas-extension/pull/1631))
- Add R language support for PROC RLANG (syntax highlighting, notebook cells, code formatting preservation)

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The SAS extension includes many [features](https://sassoftware.github.io/vscode-

- SAS syntax highlighting and help, code completion, and code snippets
- Navigate SAS Content and libraries, including table viewer
- Create notebooks for SAS, SQL, Python and other languages
- Create notebooks for SAS, SQL, Python, R, and other languages

<img src="website/static/images/featuresGlance.png"/>

Expand Down
3 changes: 3 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion client/src/components/ContentNavigator/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ const stepRef: Record<string, string> = {
sas: "a7190700-f59c-4a94-afe2-214ce639fcde",
sql: "a7190700-f59c-4a94-afe2-214ce639fcde",
python: "ab59f8c4-af9a-4608-a5d5-a8365357bb99",
rlang: "ab59f8c4-af9a-4608-a5d5-a8365357bb99",
julia: "ab59f8c4-af9a-4608-a5d5-a8365357bb99",
};

const stepTitle: Record<string, string> = {
sas: l10n.t("SAS Program"),
sql: l10n.t("SQL Program"),
python: l10n.t("Python Program"),
rlang: l10n.t("R Program"),
julia: l10n.t("Julia Program"),
};

const NODE_SPACING = 150;
Expand Down Expand Up @@ -305,7 +309,7 @@ function generateCodeListFromSASNotebook(content: string): Entry[] {
let code = cell.value;
if (code !== "") {
const language = cell.language;
if (["python", "sas", "sql"].includes(language)) {
if (["python", "sas", "sql", "rlang", "julia"].includes(language)) {
if (language === "sql") {
code = `PROC SQL;
${code};
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/notebook/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class NotebookController {
readonly controllerId = "sas-notebook-controller-id";
readonly notebookType = "sas-notebook";
readonly label = "SAS Notebook";
readonly supportedLanguages = ["sas", "sql", "python"];
readonly supportedLanguages = ["sas", "sql", "python", "r", "julia"];

private readonly _controller: vscode.NotebookController;
private _executionOrder = 0;
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/notebook/exporters/toHTML.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import {

import { readFileSync } from "fs";
import hljs from "highlight.js/lib/core";
import julia from "highlight.js/lib/languages/julia";
import python from "highlight.js/lib/languages/python";
import r from "highlight.js/lib/languages/r";
import sql from "highlight.js/lib/languages/sql";
import { marked } from "marked";
import path from "path";
Expand All @@ -27,7 +29,9 @@ import { includeLogInNotebookExport } from "../../utils/settings";
const templatesDir = path.resolve(__dirname, "../notebook/exporters/templates");

hljs.registerLanguage("python", python);
hljs.registerLanguage("r", r);
hljs.registerLanguage("sql", sql);
hljs.registerLanguage("julia", julia);

export const exportToHTML = async (
notebook: NotebookDocument,
Expand Down
16 changes: 16 additions & 0 deletions client/src/components/notebook/exporters/toSAS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ const exportCell = (cell: NotebookCell) => {
return text;
case "python":
return wrapPython(text);
case "r":
return wrapRlang(text);
case "sql":
return wrapSQL(text);
case "julia":
return wrapJulia(text);
case "markdown":
return `/*\n${text}\n*/`;
}
Expand All @@ -36,3 +40,15 @@ submit;
${code}
endsubmit;
run;`;

const wrapRlang = (code: string) => `proc rlang;
submit;
${code}
endsubmit;
run;`;

const wrapJulia = (code: string) => `proc julia;
submit;
${code}
endsubmit;
run;`;
24 changes: 24 additions & 0 deletions client/src/components/utils/SASCodeDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,22 @@ endsubmit;
run;`;
}

private wrapRlang(code: string) {
return `proc rlang;
submit;
${code}
endsubmit;
run;`;
}

private wrapJulia(code: string) {
return `proc julia;
submit;
${code}
endsubmit;
run;`;
}

private insertLogStartIndicator(code: string): string {
// add a comment line at the top of code,
// this comment line will be used as indicator to the beginning of log related with this code
Expand All @@ -198,6 +214,14 @@ ${code}`;
wrapped = this.wrapPython(wrapped);
}

if (this.parameters.languageId === "r") {
wrapped = this.wrapRlang(wrapped);
}

if (this.parameters.languageId === "julia") {
wrapped = this.wrapJulia(wrapped);
}

wrapped = this.wrapCodeWithSASProgramFileName(wrapped);

wrapped = this.wrapCodeWithPreambleAndPostamble(wrapped);
Expand Down
68 changes: 68 additions & 0 deletions client/test/components/util/SASCodeDocument.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,74 @@ run;
assert.equal(sasCodeDoc.getWrappedCode(), expected);
});

it("wrap rlang code", () => {
const parameters: SASCodeDocumentParameters = {
languageId: "r",
code: `for (x in 1:6) {
print(x)
}
print("test")`,
selectedCode: "",
htmlStyle: "Illuminate",
outputHtml: true,
uuid: "519058ad-d33b-4b5c-9d23-4cc8d6ffb163",
checkKeyword: async () => false,
};

const sasCodeDoc = new SASCodeDocument(parameters);

const expected = `/** LOG_START_INDICATOR **/
title;footnote;ods _all_ close;
ods graphics on;
ods html5(id=vscode) style=Illuminate options(bitmap_mode='inline' svg_mode='inline') body="519058ad-d33b-4b5c-9d23-4cc8d6ffb163.htm";
proc rlang;
submit;
for (x in 1:6) {
print(x)
}
print("test")
endsubmit;
run;
;*';*";*/;run;quit;ods html5(id=vscode) close;
`;

assert.equal(sasCodeDoc.getWrappedCode(), expected);
});

it("wrap julia code", () => {
const parameters: SASCodeDocumentParameters = {
languageId: "julia",
code: `# Julia code example
println("Hello from Julia!")
x = [1, 2, 3, 4, 5]
mean_val = sum(x) / length(x)`,
selectedCode: "",
htmlStyle: "Illuminate",
outputHtml: true,
uuid: "519058ad-d33b-4b5c-9d23-4cc8d6ffb163",
checkKeyword: async () => false,
};

const sasCodeDoc = new SASCodeDocument(parameters);

const expected = `/** LOG_START_INDICATOR **/
title;footnote;ods _all_ close;
ods graphics on;
ods html5(id=vscode) style=Illuminate options(bitmap_mode='inline' svg_mode='inline') body="519058ad-d33b-4b5c-9d23-4cc8d6ffb163.htm";
proc julia;
submit;
# Julia code example
println("Hello from Julia!")
x = [1, 2, 3, 4, 5]
mean_val = sum(x) / length(x)
endsubmit;
run;
;*';*";*/;run;quit;ods html5(id=vscode) close;
`;

assert.equal(sasCodeDoc.getWrappedCode(), expected);
});

it("wrap sql code", () => {
const parameters: SASCodeDocumentParameters = {
languageId: "sql",
Expand Down
42 changes: 42 additions & 0 deletions client/testFixture/formatter/expected.sas
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ def my_function():
endsubmit;
run;

proc rlang;
submit;
# Reference to variable defined in previous PROC RLANG call
print(paste("x =", x))
my_function <- function() {
print("Inside the proc step")
}
endsubmit;
run;

proc julia;
submit;
# Reference to variable defined in previous PROC JULIA call
println("x = ", x)
function my_function()
println("Inside the proc step")
end
endsubmit;
run;

proc lua;
submit;
local dsid = sas.open("sashelp.company") -- open for input
Expand Down Expand Up @@ -131,6 +151,28 @@ print('first statement after for loop')
endinteractive;
run;

proc rlang;
submit;
fruits <- c("apple", "banana", "cherry")
for (x in fruits) {
print(x)
}

print('first statement after for loop')
endsubmit;
run;

proc julia;
submit;
fruits = ["apple", "banana", "cherry"]
for x in fruits
println(x)
end

println("first statement after for loop")
endsubmit;
run;

proc lua;
submit;

Expand Down
40 changes: 40 additions & 0 deletions client/testFixture/formatter/unformatted.sas
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ def my_function():
print("Inside the proc step")
endsubmit;
run;
proc rlang;
submit;
# Reference to variable defined in previous PROC RLANG call
print(paste("x =", x))
my_function <- function() {
print("Inside the proc step")
}
endsubmit;
run;
proc julia;
submit;
# Reference to variable defined in previous PROC JULIA call
println("x = ", x)
function my_function()
println("Inside the proc step")
end
endsubmit;
run;
proc lua;
submit;
local dsid = sas.open("sashelp.company") -- open for input
Expand Down Expand Up @@ -126,6 +144,28 @@ print('first statement after for loop')
endinteractive;
run;

proc rlang;
submit;
fruits <- c("apple", "banana", "cherry")
for (x in fruits) {
print(x)
}

print('first statement after for loop')
endsubmit;
run;

proc julia;
submit;
fruits = ["apple", "banana", "cherry"]
for x in fruits
println(x)
end

println("first statement after for loop")
endsubmit;
run;

proc lua;
submit;

Expand Down
34 changes: 34 additions & 0 deletions client/testFixture/sasnb_export.sas
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,40 @@ print("Result: ", a*10 + b)
endsubmit;
run;

/*
## R Code

This is some R code
*/

/*
This is a separate note in **Markdown** format.
*/

proc rlang;
submit;
die <- 1:6
paste("Die Maths: ", die[3]*4 + die[6])
endsubmit;
run;

/*
## Julia Code

This is some Julia code
*/

/*
This is a separate note in **Markdown** format.
*/

proc julia;
submit;
dice=1:6
println("Dice Maths: ", dice[3]*4 + dice[6])
endsubmit;
run;

/*
## SAS Code
*/
Expand Down
2 changes: 1 addition & 1 deletion client/testFixture/sasnb_export.sasnb

Large diffs are not rendered by default.

Loading