diff --git a/README.md b/README.md
index bdfd9ef..e11f80f 100644
--- a/README.md
+++ b/README.md
@@ -140,7 +140,7 @@ SHA256 digest for macroArray: 0F1B985E2FC34C91D2A3BD237DC294502A76913B71266D7670
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
-- **BasePlus**\[0.9\] adds a bunch of functionalities I am missing in BASE SAS, such as:
+- **BasePlus**\[0.99\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```
call arrMissToRight(myArray);
call arrFillMiss(17, myArray);
@@ -154,7 +154,7 @@ format x bool.;
%put %getVars(sashelp.class, pattern = ght$, sep = +, varRange = _numeric_);
```
-SHA256 digest for BasePlus: B25A3992B6FCD13528BEE462B3ADD0F5A6D15E607A6DABAA984CA66B0AD69415
+SHA256 digest for BasePlus: 7933E6BCFDCA7C04EAAC537773574799759007A5D2AED639E86CF4EA631F1351
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
diff --git a/packages/README.md b/packages/README.md
index 99d0a2b..e2d3a10 100644
--- a/packages/README.md
+++ b/packages/README.md
@@ -90,7 +90,7 @@ SHA256 digest for macroArray: 0F1B985E2FC34C91D2A3BD237DC294502A76913B71266D7670
---
-- **BasePlus**\[0.9\] adds a bunch of functionalities I am missing in BASE SAS, such as:
+- **BasePlus**\[0.99\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```
call arrMissToRight(myArray);
call arrFillMiss(17, myArray);
@@ -104,7 +104,7 @@ format x bool.;
%put %getVars(sashelp.class, pattern = ght$, sep = +, varRange = _numeric_);
```
-SHA256 digest for BasePlus: B25A3992B6FCD13528BEE462B3ADD0F5A6D15E607A6DABAA984CA66B0AD69415
+SHA256 digest for BasePlus: 7933E6BCFDCA7C04EAAC537773574799759007A5D2AED639E86CF4EA631F1351
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
diff --git a/packages/SHA256_for_packages.txt b/packages/SHA256_for_packages.txt
index eac0768..1a8208a 100644
--- a/packages/SHA256_for_packages.txt
+++ b/packages/SHA256_for_packages.txt
@@ -1,3 +1,6 @@
+/* 20201202 */
+BasePlus: 7933E6BCFDCA7C04EAAC537773574799759007A5D2AED639E86CF4EA631F1351
+
/* 20201130 */
DFA: 1FC8D030D576C33F1B5DEB27E17534946209BC148D57A1357CA025ED1E69AEB8
diff --git a/packages/baseplus.md b/packages/baseplus.md
index 44a75cb..c4989e8 100644
--- a/packages/baseplus.md
+++ b/packages/baseplus.md
@@ -33,12 +33,20 @@
* [`%dedupListP()` macro](#deduplistp-macro)
* [`%dedupListX()` macro](#deduplistx-macro)
* [`%QdedupListX()` macro](#qdeduplistx-macro)
-
+ * [`brackets.` format](#brackets-format)
+ * [`semicolon.` format](#semicolon-format)
+ * [`bracketsC()` function](#bracketsc-function)
+ * [`bracketsN()` function](#bracketsn-function)
+ * [`semicolonC()` function](#semicolonc-function)
+ * [`semicolonN()` function](#semicolonn-function)
+ * [`%zipEvalf()` macro](#zipevalf-macro)
+ * [`%QzipEvalf()` macro](#qzipevalf-macro)
+
* [License](#license)
---
-# The BasePlus package [ver. 0.9] ###############################################
+# The BasePlus package [ver. 0.99] ###############################################
The **BasePlus** package implements useful
functions and functionalities I miss in the BASE SAS.
@@ -162,47 +170,61 @@ Kudos to all who inspired me to generate this package:
%put *%dedupListS(&list.)*;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**Example 8**: Zip elements of two space separated list.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let x = %zipEvalf(1 2 3 4 5 6, 2018 2019 2020, argMd=5, function=MDY, format=date11.);
+%put &=x;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
---
Package contains:
- 1. macro deduplistc
- 2. macro deduplistp
- 3. macro deduplists
- 4. macro deduplistx
- 5. macro getvars
- 6. macro qdeduplistx
- 7. macro qgetvars
- 8. macro symdelglobal
- 9. format bool
- 10. format boolz
- 11. format ceil
- 12. format floor
- 13. format int
- 14. functions arrfill
- 15. functions arrfillc
- 16. functions arrmissfill
- 17. functions arrmissfillc
- 18. functions arrmisstoleft
- 19. functions arrmisstoleftc
- 20. functions arrmisstoright
- 21. functions arrmisstorightc
- 22. functions catxfc
- 23. functions catxfi
- 24. functions catxfj
- 25. functions catxfn
- 26. functions deldataset
- 27. proto qsortincbyprocproto
- 28. functions frommissingtonumberbs
- 29. functions fromnumbertomissing
- 30. functions quicksort4notmiss
- 31. functions quicksorthash
- 32. functions quicksorthashsddv
- 33. functions quicksortlight
+1. macro deduplistc
+2. macro deduplistp
+3. macro deduplists
+4. macro deduplistx
+5. macro getvars
+6. macro qdeduplistx
+7. macro qgetvars
+8. macro qzipevalf
+9. macro symdelglobal
+10. macro zipevalf
+11. format bool
+12. format boolz
+13. format ceil
+14. format floor
+15. format int
+16. functions arrfill
+17. functions arrfillc
+18. functions arrmissfill
+19. functions arrmissfillc
+20. functions arrmisstoleft
+21. functions arrmisstoleftc
+22. functions arrmisstoright
+23. functions arrmisstorightc
+24. functions bracketsc
+25. functions bracketsn
+26. functions catxfc
+27. functions catxfi
+28. functions catxfj
+29. functions catxfn
+30. functions deldataset
+31. functions semicolonc
+32. functions semicolonn
+33. format brackets
+34. format semicolon
+35. proto qsortincbyprocproto
+36. functions frommissingtonumberbs
+37. functions fromnumbertomissing
+38. functions quicksort4notmiss
+39. functions quicksorthash
+40. functions quicksorthashsddv
+41. functions quicksortlight
*SAS package generated by generatePackage, version 20201115*
The SHA256 hash digest for package BasePlus:
-`B25A3992B6FCD13528BEE462B3ADD0F5A6D15E607A6DABAA984CA66B0AD69415`
+`7933E6BCFDCA7C04EAAC537773574799759007A5D2AED639E86CF4EA631F1351`
---
# Content description ############################################################################################
@@ -2491,6 +2513,425 @@ XlistXofXxXseparatedXvalues
---
+## >>> `brackets.` format: <<< #######################
+
+The **brackets** format adds brackets around a text or a number.
+Leading and trailing spaces are dropped before adding brackets.
+
+### EXAMPLES AND USECASES: ####################################################
+
+**Example 1.**
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+data _null_;
+ input x;
+ if x < 0 then put x= brackets.;
+ else put x= best32.;
+cards;
+2
+1
+0
+-1
+-2
+;
+run;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+---
+
+## >>> `semicolon.` format: <<< #######################
+
+The **semicolon** format adds semicolon after text or number.
+Leading and trailing spaces are dropped before adding semicolon.
+
+### EXAMPLES AND USECASES: ####################################################
+
+**Example 1.**
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+data _null_;
+ x = 1;
+ y = "A";
+ put x= semicolon. y= $semicolon.;
+run;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+---
+
+## >>> `bracketsC()` function: <<< #######################
+
+The **bracketsC()** function is internal function used by the *brackets* format.
+Returns character value of length 32767.
+
+### SYNTAX: ###################################################################
+
+The basic syntax is the following:
+~~~~~~~~~~~~~~~~~~~~~~~sas
+bracketsC(X)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Arguments description**:
+
+1. `X` - Character value.
+
+---
+
+## >>> `bracketsN()` function: <<< #######################
+
+The **bracketsN()** function is internal function used by the *brackets* format.
+Returns character value of length 34.
+
+### SYNTAX: ###################################################################
+
+The basic syntax is the following:
+~~~~~~~~~~~~~~~~~~~~~~~sas
+bracketsN(X)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Arguments description**:
+
+1. `X` - Numeric value.
+
+---
+
+## >>> `semicolonC()` function: <<< #######################
+
+The **semicolonC()** function is internal function used by the *semicolon* format.
+Returns character value of length 32767.
+
+### SYNTAX: ###################################################################
+
+The basic syntax is the following:
+~~~~~~~~~~~~~~~~~~~~~~~sas
+semicolonC(X)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Arguments description**:
+
+1. `X` - Character value.
+
+---
+
+## >>> `semicolonN()` function: <<< #######################
+
+The **semicolonN()** function is internal function used by the *semicolon* format.
+Returns character value of length 33.
+
+### SYNTAX: ###################################################################
+
+The basic syntax is the following:
+~~~~~~~~~~~~~~~~~~~~~~~sas
+semicolonN(X)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Arguments description**:
+
+1. `X` - Numeric value.
+
+---
+
+## >>> `%QzipEvalf()` macro: <<< #######################
+
+The zipEvalf() and QzipEvalf() macro functions
+allow to use a function on elements of pair of
+space separated lists.
+
+For two space separated lists of text strings the corresponding
+elements are taken and the macro applies a function, provided by user,
+to calculate result of the function on taken elements.
+
+When one of the lists is shorter then elements are "reused" starting
+from the beginning.
+
+The zipEvalf() returns unquoted value [by %unquote()].
+The QzipEvalf() returns quoted value [by %superq()].
+
+See examples below for the details.
+
+The `%QzipEvalf()` macro executes like a pure macro code.
+
+### SYNTAX: ###################################################################
+
+The basic syntax is the following, the `<...>` means optional parameters:
+~~~~~~~~~~~~~~~~~~~~~~~sas
+%QzipEvalf(
+ first
+ ,second
+ <,function=>
+ <,operator=>
+ <,argBf=>
+ <,argMd=>
+ <,argAf=>
+ <,format=>
+)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Arguments description**:
+
+1. `first` - *Required*, a space separated list of texts.
+
+2. `second` - *Required*, a space separated list of texts.
+
+* `function = cat` - *Optional*, default value is `cat`,
+ a function which will be applied
+ to corresponding pairs of elements of
+ the first and the second list.
+
+* `operator =` - *Optional*, default value is empty,
+ arithmetic infix operator used with elements
+ the first and the second list. The first
+ list is used on the left side of the operator
+ the second list is used on the right side
+ of the operator.
+
+* `argBf =` - *Optional*, default value is empty,
+ arguments of the function inserted
+ *before* elements the first list.
+ If multiple should be comma separated.
+
+* `argMd =` - *Optional*, default value is empty,
+ arguments of the function inserted
+ *between* elements the first list and
+ the second list.
+ If multiple should be comma separated.
+
+* `argAf =` - *Optional*, default value is empty,
+ arguments of the function inserted
+ *after* elements the second list.
+ If multiple should be comma separated.
+
+* `format=` - *Optional*, default value is empty,
+ indicates a format which should be used
+ to format the result, does not work when
+ the `operator=` is used.
+
+### EXAMPLES AND USECASES: ####################################################
+
+See examples in `%zipEvalf()` help for the details.
+
+---
+
+## >>> `%zipEvalf()` macro: <<< #######################
+
+The zipEvalf() and QzipEvalf() macro functions
+allow to use a function on elements of pair of
+space separated lists.
+
+For two space separated lists of text strings the corresponding
+elements are taken and the macro applies a function, provided by user,
+to calculate result of the function on taken elements.
+
+When one of the lists is shorter then elements are "reused" starting
+from the beginning.
+
+The zipEvalf() returns unquoted value [by %unquote()].
+The QzipEvalf() returns quoted value [by %superq()].
+
+See examples below for the details.
+
+The `%zipEvalf()` macro executes like a pure macro code.
+
+### SYNTAX: ###################################################################
+
+The basic syntax is the following, the `<...>` means optional parameters:
+~~~~~~~~~~~~~~~~~~~~~~~sas
+%zipEvalf(
+ first
+ ,second
+ <,function=>
+ <,operator=>
+ <,argBf=>
+ <,argMd=>
+ <,argAf=>
+ <,format=>
+)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Arguments description**:
+
+1. `first` - *Required*, a space separated list of texts.
+
+2. `second` - *Required*, a space separated list of texts.
+
+* `function = cat` - *Optional*, default value is `cat`,
+ a function which will be applied
+ to corresponding pairs of elements of
+ the first and the second list.
+
+* `operator =` - *Optional*, default value is empty,
+ arithmetic infix operator used with elements
+ the first and the second list. The first
+ list is used on the left side of the operator
+ the second list is used on the right side
+ of the operator.
+
+* `argBf =` - *Optional*, default value is empty,
+ arguments of the function inserted
+ *before* elements the first list.
+ If multiple should be comma separated.
+
+* `argMd =` - *Optional*, default value is empty,
+ arguments of the function inserted
+ *between* elements the first list and
+ the second list.
+ If multiple should be comma separated.
+
+* `argAf =` - *Optional*, default value is empty,
+ arguments of the function inserted
+ *after* elements the second list.
+ If multiple should be comma separated.
+
+* `format=` - *Optional*, default value is empty,
+ indicates a format which should be used
+ to format the result, does not work when
+ the `operator=` is used.
+
+### EXAMPLES AND USECASES: ####################################################
+
+**EXAMPLE 1.** Simple concatenation of elements:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let x = %zipEvalf(1 2 3 4 5 6, q w e r t y);
+%put &=x;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 2.** Shorter list is "reused":
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let x = %zipEvalf(1 2 3 4 5 6, a b c);
+%put &=x;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 3.** Use of the `operator=`, shorter list is "reused":
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let y = %zipEvalf(1 2 3 4 5 6, 100 200, operator = +);
+%put &=y;
+
+%let z = %zipEvalf(1 2 3 4 5 6 8 9 10, 1 2 3 4 5 6 8 9 10, operator = **);
+%put &=z;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 4.** Format result:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let x = %zipEvalf(1 2 3 4 5 6, q w e r t y, format=$upcase.);
+%put &=x;
+
+%put *
+%zipEvalf(
+ ą ż ś ź ę ć ń ó ł
+,Ą Ż Ś Ź Ę Ć Ń Ó Ł
+,format = $brackets.
+)
+*;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 5.** Use with macrovariables:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let abc = 10 100 1000;
+%put *
+%zipEvalf(
+%str(1 2 3 4 5 6 7 8 9)
+,&abc.
+,function = sum
+)
+*;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 6.** If one of elements is empty:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%put *
+%zipEvalf(
+ abc efg
+,
+)
+*;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 7.** Use of the `function=`, shorter list is "reused":
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%put *
+%zipEvalf(
+ a b c
+,efg
+,function = catx
+,argBf = %str(,)
+,format = $brackets.
+)
+*;
+
+%put *
+%zipEvalf(
+ a b c
+,efg
+,function = catx
+,argBf = %str( )
+,format = $upcase.
+)
+*;
+
+%put *
+%zipEvalf(
+ %str(! @ # $ [ ] % ^ & * )
+,1 2 3 4 5 6 7 8 9
+,function = catx
+,argBf = %str( )
+,format = $quote.
+)
+*;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 8.** Use inside resolve:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+data _null_;
+z = resolve('
+%zipEvalf(
+ %nrstr(! @ # $ [ ] % ^ & *)
+,1 2 3 4 5 6 7 8 9
+,function = catx
+,argBf = %str(.)
+,format = $quote.
+)');
+put z=;
+run;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 9.** Use in data step:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+data test;
+ %zipEvalf(
+ a b c d e f g
+ ,1 2 3 4 5 6 7
+ ,function = catx
+ ,argBf = =
+ ,format = $semicolon.
+ )
+run;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 10.** With 9.4M6 hashing() function:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%put %zipEvalf(MD5 SHA1 SHA256 SHA384 SHA512 CRC32, abcd, function = HASHING);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+**EXAMPLE 11.** Use middle argument:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
+%let x = %zipEvalf(1 2 3 4 5 6, 2020, argMd=5, function=MDY, format=date11.);
+%put &=x;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+---
+
+
+
+
## License ####################################################################
Copyright (c) 2020 Bartosz Jablonski
diff --git a/packages/baseplus.zip b/packages/baseplus.zip
index a67760b..94c186a 100644
Binary files a/packages/baseplus.zip and b/packages/baseplus.zip differ