/*+SPFint_gnPckg_markdown+*/ %macro SPFint_gnPckg_markdown()/secure minoperator des='SAS Packages Framework internal macro. Executable only inside the %generatePackage() macro. The macro encapsulates the markdown documentation part of the process. Version 20251228.'; /* macro picks up all macrovariables from external scope, so from the %generatePackage() macro */ %if %sysmexecname(%sysmexecdepth-1) in (GENERATEPACKAGE) %then %do; /*=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=*/ /* generate MarkDown documentation file */ /* check param value */ %if %superq(markdownDoc) NE 1 %then %let markdownDoc=0; /* if true then execute */ %if &markdownDoc.=1 %then %do; %if %superq(createPackageContentStatus) NE 0 %then %do; %put ERROR- ** [&sysmacroname.] **; %put ERROR: ** ERRORS IN PACKAGE CONTENT CREATION! **; %put ERROR- ** NO MARKDOWN DOCUMMENTATION WILL BE GENERATED. **; %GOTO NOmarkdownDoc; %end; /*= generate MarkDown documentation START =================================================================================*/ %put NOTE-; %put NOTE: Preparing markdown documentation file.; %put NOTE- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; %put NOTE-; %local MarkDownOptionsTmp; %let MarkDownOptionsTmp = %sysfunc(getoption(notes)) %sysfunc(getoption(source)) msglevel=%sysfunc(getoption(msglevel)); options NOnotes NOsource msglevel=N; filename &zipReferrence. "&buildLocation./%sysfunc(lowcase(&packageName.)).md"; filename &_PackageFileref_. ZIP "&buildLocation./%sysfunc(lowcase(&packageName.)).zip"; data &filesWithCodes.markdown; /* break if no data */ if NOBS = 0 then stop; file &zipReferrence. encoding = &packageEncoding.; put "# Documentation for the `&packageName.` package."; length packageLicense packageGenerated $ 64 packageTitle packageAuthor packageMaintainer $ 4096 packageHashF packageHashC $ 128 ; packageLicense=symget("packageLicense"); packageTitle=symget("packageTitle"); packageGenerated=symget("packageGenerated"); packageAuthor=symget("packageAuthor"); packageMaintainer=symget("packageMaintainer"); packageHashF=symget("packageHashF"); packageHashC=symget("packageHashC"); drop package:; put " " / 64*"-" / " " / ' *' packageTitle +(-1)'* ' / " " / 64*"-" / " " / "### Version information:" / " " / "- Package: &packageName." / "- Version: &packageVersion." / "- Generated: " packageGenerated / "- Author(s): " packageAuthor / "- Maintainer(s): " packageMaintainer / "- License: " packageLicense / "- File SHA256: `" packageHashF +(-1) "` for this version" / "- Content SHA256: `" packageHashC +(-1) "` for this version" / " " / "---" / " "; put "# The `&packageName.` package, version: `&packageVersion.`;" / " " / "---" / " "; do until (EOF); infile &_PackageFileref_.(description.sas) end = EOF; input; if upcase(strip(_infile_)) =: "DESCRIPTION END:" then printer = 0; if printer then put _infile_; if upcase(strip(_infile_)) =: "DESCRIPTION START:" then printer = 1; end; put " " / "---" / " "; %if %superq(packageRequired) ne %then %do; put " " / "---" / " "; length req $ 256; put "Required SAS Components: "; do req = &packageRequired. ; put @3 "-" @5 req; end ; %end; %if %superq(packageReqPackages) ne %then %do; put " " / "---" / " "; length req2 $ 256; put "Required SAS Packages: "; do req2 = &packageReqPackages.; put @3 "-" @5 req2; end ; %end; put " " / "---" / " "; %if %superq(additionalContent) NE %then %do; put " " / "---" / " "; put 'Package contains additional content, run: `%loadPackageAddCnt(' "&packageName." ')` to load it' / "or look for the `%sysfunc(lowcase(&packageName.))_AdditionalContent` directory in the `packages` fileref" / "localization (only if additional content was deployed during the installation process)."; %end; put " " / "---------------------------------------------------------------------" / " " / "*SAS package generated by SAS Package Framework, version `20251228`,*" / "*under `&sysscp.`(`&sysscpl.`) operating system,*" / "*using SAS release: `&sysvlong4.`.*" / " " / "---------------------------------------------------------------------" / " "; put "# The `&packageName.` package content"; put "The `&packageName.` package consists of the following content:" / " "; EOFDS = 0; do until(EOFDS); /* content is created during package creation */ set &filesWithCodes. end = EOFDS nobs = NOBS curobs = CUROBS; if upcase(type) in: ('TEST') then continue; /* exclude tests */ /* To exclude file from being added to the documentation insert the "excluding" text(see below) as a comment in the FIRST or SECOND line of the file! Do not add spaces. For each file the first line is read in and checked. */ length _FILEVARPATH_ $ 4096; _FILEVARPATH_=catx("/",base,folder,file); infile _dummy_ FILEVAR=_FILEVARPATH_; input; if strip(_infile_) IN ( '/*##DoNotUse4Documentation##*/' '/*##ExcludeFromDocumentation##*/' '/*##ExcludeFromMarkdownDoc##*/' ) then continue; /* exclude file from documentation after FIRST line */ input; if strip(_infile_) IN ( '/*##DoNotUse4Documentation##*/' '/*##ExcludeFromDocumentation##*/' '/*##ExcludeFromMarkdownDoc##*/' ) then continue; /* exclude file from documentation after SECOND line */ /* this is because %splitCodeForPackage() macro adds one extra line */ type2=type; length link $ 256; link=catx("-",compress(fileshort,,"KAD"),type,CUROBS); length fileshort $ 256; select; when (upcase(type) =: "MACRO" ) do; fileshort2 = cats('`%', fileshort, "()`"); type2='macro'; end; when (upcase(type) =: "FORMAT" ) do; fileshort2 = cats("`$", fileshort, ".`"); type2='format/informat'; end; when (upcase(type) =: "FUNCTION" ) do; fileshort2 = cats("`", fileshort, "()`"); type2='function'; end; when (upcase(type) =: "IMLMODULE") fileshort2 = cats("`", fileshort, "()`"); when (upcase(type) =: "PROTO" ) fileshort2 = cats("`", fileshort, "()`"); when (upcase(type) =: "CASLUDF" ) fileshort2 = cats("`", fileshort, "()`"); otherwise fileshort2 = cats("`", fileshort, "`"); end; contentObs + 1; put @1 contentObs +(-1) '. [' fileshort2 type2'](#' link ')'; output; end; put " " / " "; contentObs+1; put @1 contentObs +(-1) '. [License note](#license)'; put " " / "---" / " "; putlog "Doc. note with general information ready."; stop; run; /* loop through content and print info to the MD file */ data _null_; if 0 = NOBS then stop; do until(EOFDS); set &filesWithCodes.markdown end = EOFDS nobs = NOBS curobs=CUROBS; length memberX $ 1024; memberX = cats("_",folder,".",file); /* inner data step in call execute to read each embedded file */ call execute("data _null_; "); call execute(" file &zipReferrence. encoding = &packageEncoding. MOD; "); call execute(' put ''## ' !! catx(" ",fileshort2,type2) !! ' ######'';'); call execute(' infile &_PackageFileref_.(' || strip(memberX) || ') end = EOF; '); call execute(" printer = 0; "); call execute(" do until(EOF); "); call execute(" input; length _endhelpline_ _starthelpline_ $ 32767; "); call execute(" _endhelpline_ = upcase(reverse(strip(_infile_))); "); call execute(" if 18 <= lengthn(_endhelpline_) AND _endhelpline_ =: '/*** DNE PLEH ***/' then printer = 0; "); /* ends with HELP END */ call execute(" if printer then put _infile_; "); call execute(" _starthelpline_ = upcase(strip(_infile_)); "); call execute(" if 20 <= lengthn(_starthelpline_) AND _starthelpline_ =: '/*** HELP START ***/' then printer = 1 ; "); /* starts with HELP START */ call execute(" end; "); call execute(' put " " / "---" / " "; '); call execute(' putlog ''Doc. note ' !! cats(CUROBS) !! ' for ' !! catx(" ",fileshort2,type2) !! ' ready.'';'); call execute(" stop; "); call execute("run; "); end; stop; run; /* license info */ data _null_; file &zipReferrence. encoding = &packageEncoding. MOD; putlog "Doc. note with license ready."; put " " / "---" / " " / '# License ######' / " " ; do until (EOF_L); infile &_PackageFileref_.(license.sas) end = EOF_L; input; put _infile_; end; put " " / "---" / " "; stop; run; options &MarkDownOptionsTmp.; %put NOTE: Markdown file generated.; filename &zipReferrence. list; %put NOTE- ; options NOnotes NOsource msglevel=N; filename &zipReferrence. clear; filename &_PackageFileref_. clear; options &MarkDownOptionsTmp.; /*= generate MarkDown documentation END =================================================================================*/ %NOmarkdownDoc: %end; /*=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=*/ %end; %else %do; %put INFO: SAS Packages Framework internal macro. Executable only inside the %nrstr(%%)generatePackage() macro.; %end; %mend SPFint_gnPckg_markdown;