|
Macros for SAS Application Developers
https://github.com/sasjs/core |
Much quality. Many standards. The Macro Core library exists to save time and development effort! Herein ye shall find a veritable host of MIT-licenced, production quality SAS macros. These are a mix of tools, utilities, functions and code generators that are useful in the context of Application Development on the SAS platform (eg https://datacontroller.io). Contributions are welcome.
You can download and compile them all in just two lines of SAS code:
Documentation: https://core.sasjs.io
mf_, mp_mddl_(lib)_ -> where lib can be "SAS" (in relation to a SAS component) or "DC" (in relation to a Data Controller component)This library will not be used for storing data entries (such as formats or datalines). Where this becomes necessary in the future, a new repo will be created, in order to keep the NPM bundle size down (for the benefit of those looking to embed purely macros in their applications).
mcf_The fcmp macros are used to generate fcmp functions, and can be used with or without the proc fcmp wrapper.
Wait - this is a macro library - what is LUA doing here? Well, it is a little known fact that you CAN run LUA within a SAS Macro. It has to be written to a text file with a .lua extension, from where you can include it. So, without using the proc lua wrapper.
To contribute, simply write your freeform LUA in the LUA folder. Then run the build.py, which will convert all files with a ".lua" extension into a macro wrapper with an ml_ prefix (embedding the necessary data step put statements). You can then use your module in any program by running:
ml_Macros used in SAS EBI, which connect to the metadata server.
mm_mmx_These macros are used for building applications using @sasjs/server - an open source REST API for Desktop SAS.
ms_Macros used for interfacing with SAS Viya.
mv_, mvf_Sometimes it is helpful to use a macro that can be used interchangeably regardless of the server type on which is is running (SASVIYA, SAS9, SASJS).
mx_First, download the repo to a location your SAS system can access. Then update your sasautos path to include the components you wish to have available, eg:
The above can be done directly in your sas program, via an autoexec, or an initialisation program.
Alternatively - for quick access - simply run the following! This file contains all the macros.
This repo ships with agent skills (in .agents/skills) to help coding assistants write idiomatic SAS and follow the @sasjs/core standards. The canonical versions live in the sasjs/skills repo and cover SAS language, @sasjs/core, @sasjs/adapter, @sasjs/cli, the SASjs framework, and @sasjs/server.
To install or update them in your own project, run:
The Macro Core documentation is created using doxygen. A full list of attributes can be found here but the following are most relevant:
All macros must be commented in the doxygen format, to enable the online documentation.
SAS code can contain one of two types of dependency - SAS Macros, and SAS Includes. When compiling projects using the SASjs CLI the doxygen header is scanned for @li items under the following headers:
The CLI can then extract all the dependencies and insert as precode (SAS Macros) or in a temp engine fileref (SAS Includes) when creating SAS Jobs and Services (and Tests).
When contributing to this library, it is therefore important to ensure that all dependencies are listed in the header in this format.
&var not &var.) unless necessary to prevent incorrect resolutionmend statement must contain the macro name, eg mend mymacro; (enforced by the hasMacroNameInMend lint rule).macro x(); not macro x;work.blah, not blah). This is to avoid contention when options DATASTMTCHK=ALLKEYWORDS is in effect, or the USER library is active.data ; set sashelp.class; run; data &output; set &syslast; run;_SASJS_ prefix and be declared in mp_init.sas - see mp_init.sasquit; for proc sql is essential, to avoid WARNING: You cannot disconnect or terminate session XXXX until the procedure completes. when terminating CAS sessions in Viya.We are currently on major release v6. The following breaking changes were applied as part of the v6 release:
_SASJS_ prefix, matching the names sasjs/server sets in its pre-programs. SASJSWORK is now _SASJS_WORK, SASJS_INIT_NUM is _SASJS_INIT_NUM, SASJS_INIT_DTTM is _SASJS_INIT_DTTM, SASJSPROCESSMODE is _SASJS_PROCESSMODE and SASJS_FUNCTIONS is _SASJS_FUNCTIONS. Code that built paths, tests or ignore lists from the old names must read the new ones - core no longer creates the old names and no alias variables are declared. The one name that still answers to its old form is the initialisation marker described in the next point, which is honoured rather than created.prefix= parameter was removed, and the prefix is hard-coded as _SASJS_. Call mp_init() with no arguments. The "do not initialise" marker is renamed with everything else: set _SASJS_INIT (formerly SASJS_PREFIX) in the autoexec, to any value, to suppress initialisation. SASJS_PREFIX still suppresses initialisation if it is already set, so an existing autoexec keeps working unchanged; core no longer sets it.Releases are cut by semantic-release from the commit messages on main, so the squashed PR message is what decides the version:
BREAKING CHANGE: footer in the commit body. The ! after the type on its own did not bump the major on this pipeline - the v6 rename merged as feat!: and shipped as a patch release.main may carry a skip marker ([skip ci] and friends), including one copied in by the squashed commit list. A skip marker suppresses every workflow for that push, the release job included, and nothing is published.If you find this library useful, please leave a star and help us grow our star graph!
The following repositories are also worth checking out:

Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!